diff --git a/.gitignore b/.gitignore
index cdb7c1e1..c8351d3f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,11 @@
translations/*.qm
build
version.js
+# IOS stuff below
+moc_*
+*.o
+*.mak
+*.build
+*.xcodeproj
+monero-wallet-gui_plugin_import.cpp
+monero-wallet-gui_qml_plugin_import.cpp
diff --git a/LeftPanel.qml b/LeftPanel.qml
index 6f843fc7..e9fa7467 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
@@ -69,6 +70,8 @@ Rectangle {
width: (isMobile)? appWindow.width : 260
color: "#FFFFFF"
+ anchors.bottom: parent.bottom
+ anchors.top: parent.top
// Item with monero logo
Item {
@@ -138,8 +141,8 @@ Rectangle {
visible: !isMobile
Item {
anchors.verticalCenter: parent.verticalCenter
- height: 26
- width: 50
+ height: 26 * scaleRatio
+ width: 50 * scaleRatio
Image {
anchors.centerIn: parent
@@ -228,7 +231,8 @@ Rectangle {
Flickable {
- contentHeight: 500
+ id:flicker
+ contentHeight: 500 * scaleRatio
anchors.fill: parent
clip: true
@@ -239,7 +243,7 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
-
+ clip: true
property var previousButton: transferButton
// ------------- Dashboard tab ---------------
@@ -393,6 +397,7 @@ Rectangle {
// ------------- Mining tab ---------------
MenuButton {
id: miningButton
+ visible: !isAndroid && !isIOS
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Mining") + translationManager.emptyString
@@ -483,10 +488,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
@@ -494,6 +522,7 @@ Rectangle {
anchors.right: parent.right
anchors.bottom: (progressBar.visible)? progressBar.top : parent.bottom;
connected: Wallet.ConnectionStatus_Disconnected
+ height: 58 * scaleRatio
}
ProgressBar {
@@ -501,8 +530,9 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
+ height: 35 * scaleRatio
}
- }
+ } // menuRect
diff --git a/MiddlePanel.qml b/MiddlePanel.qml
index 404a9d40..a008a62a 100644
--- a/MiddlePanel.qml
+++ b/MiddlePanel.qml
@@ -29,6 +29,7 @@
import QtQml 2.0
import QtQuick 2.2
+// QtQuick.Controls 2.0 isn't stable enough yet. Needs more testing.
//import QtQuick.Controls 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
@@ -47,7 +48,7 @@ Rectangle {
property string balanceText
property string unlockedBalanceLabelText: qsTr("Unlocked Balance") + translationManager.emptyString
property string unlockedBalanceText
- property int minHeight: (appWindow.height > 800) ? appWindow.height : 800
+ property int minHeight: (appWindow.height > 800) ? appWindow.height : 800 * scaleRatio
// property int headerHeight: header.height
property Transfer transferView: Transfer { }
@@ -58,6 +59,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 +95,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"
@@ -132,7 +107,7 @@ Rectangle {
}, State {
name: "Transfer"
PropertyChanges { target: root; currentView: transferView }
- PropertyChanges { target: mainFlickable; contentHeight: 1000 }
+ PropertyChanges { target: mainFlickable; contentHeight: 1000 * scaleRatio }
}, State {
name: "Receive"
PropertyChanges { target: root; currentView: receiveView }
@@ -152,11 +127,15 @@ Rectangle {
}, State {
name: "Settings"
PropertyChanges { target: root; currentView: settingsView }
- PropertyChanges { target: mainFlickable; contentHeight: 1200 }
+ PropertyChanges { target: mainFlickable; contentHeight: 1200 * scaleRatio }
}, State {
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 + 200 * scaleRatio }
}
]
@@ -187,6 +166,11 @@ Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
+
+ onFlickingChanged: {
+ releaseFocus();
+ }
+
// Disabled scrollbars, gives crash on startup on windows
// ScrollIndicator.vertical: ScrollIndicator { }
// ScrollBar.vertical: ScrollBar { } // uncomment to test
@@ -195,11 +179,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/RightPanel.qml b/RightPanel.qml
index c4626835..25befca2 100644
--- a/RightPanel.qml
+++ b/RightPanel.qml
@@ -38,121 +38,4 @@ Rectangle {
id: root
width: 330
color: "#FFFFFF"
-
- function updateTweets() {
- tabView.twitter.item.updateTweets()
- }
-
-
- TabView {
- id: tabView
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.bottom: styledRow.top
- anchors.leftMargin: 14
- anchors.rightMargin: 14
- anchors.topMargin: 40
- property alias twitter: twitter
-
-
-
-
- Tab { id: twitter; title: qsTr("Twitter"); source: "tabs/Twitter.qml" }
- Tab { title: qsTr("News") + translationManager.emptyString }
- Tab { title: qsTr("Help") + translationManager.emptyString }
- Tab { title: qsTr("About") + translationManager.emptyString }
-
-
-
- style: TabViewStyle {
- frameOverlap: 0
- tabOverlap: 0
-
- tab: Rectangle {
- implicitHeight: 31
- implicitWidth: styleData.index === tabView.count - 1 ? tabView.width - (tabView.count - 1) * 68 : 68
-
- Text {
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: 12
- anchors.rightMargin: 12
- elide: Text.ElideRight
- font.family: "Arial"
- font.pixelSize: 14
- color: styleData.selected ? "#FF4E40" : "#4A4646"
- text: styleData.title
- }
-
- Rectangle {
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.right: parent.right
- width: 1
- color: "#DBDBDB"
- visible: styleData.index !== tabView.count - 1
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.bottomMargin: -1
- height: 1
- color: styleData.selected ? "#FFFFFF" : "#DBDBDB"
- }
- }
-
- frame: Rectangle {
- color: "#FFFFFF"
- anchors.fill: parent
- Rectangle {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- //anchors.topMargin: 1
- height: 1
- color: "#DBDBDB"
- }
- }
- }
- }
-
- Row {
- id: styledRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
-
- Rectangle { height: 8; width: parent.width / 5; color: "#FFE00A" }
- Rectangle { height: 8; width: parent.width / 5; color: "#6B0072" }
- Rectangle { height: 8; width: parent.width / 5; color: "#FF6C3C" }
- Rectangle { height: 8; width: parent.width / 5; color: "#FFD781" }
- Rectangle { height: 8; width: parent.width / 5 - 30; color: "#FF4F41" }
- }
-
- Rectangle {
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- height: 1
- color: "#DBDBDB"
- }
-
- Rectangle {
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.right: parent.right
- width: 1
- color: "#DBDBDB"
- }
-
- // indicate disabled state
-// Desaturate {
-// anchors.fill: parent
-// source: parent
-// desaturation: root.enabled ? 0.0 : 1.0
-// }
}
diff --git a/components/AddressBookTable.qml b/components/AddressBookTable.qml
index abf72371..4d281440 100644
--- a/components/AddressBookTable.qml
+++ b/components/AddressBookTable.qml
@@ -144,8 +144,10 @@ ListView {
onOptionClicked: {
// Ensure tooltip is closed
appWindow.toolTip.visible = false;
- if(option === 0)
+ if(option === 0) {
clipboard.setText(address)
+ appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3)
+ }
else if(option === 1){
console.log("Sending to: ", address +" "+ paymentId);
middlePanel.sendTo(address, paymentId, description);
diff --git a/components/CheckBox.qml b/components/CheckBox.qml
index ffe585c3..267106b1 100644
--- a/components/CheckBox.qml
+++ b/components/CheckBox.qml
@@ -29,61 +29,70 @@
import QtQuick 2.0
import QtQuick.Layouts 1.1
-Item {
+RowLayout {
id: checkBox
property alias text: label.text
property string checkedIcon
property string uncheckedIcon
property bool checked: false
property alias background: backgroundRect.color
- property int fontSize: 14
+ property int fontSize: 14 * scaleRatio
property alias fontColor: label.color
signal clicked()
- height: 25
- width: label.x + label.width
- Layout.minimumWidth: label.x + label.contentWidth
- clip: true
+ height: 25 * scaleRatio
- Rectangle {
- anchors.left: parent.left
- height: parent.height - 1
- width: 25
- //radius: 4
- y: 0
- color: "#DBDBDB"
+ function toggle(){
+ checkBox.checked = !checkBox.checked
+ checkBox.clicked()
}
- Rectangle {
- id: backgroundRect
- anchors.left: parent.left
- height: parent.height - 1
- width: 25
- //radius: 4
- y: 1
- color: "#FFFFFF"
-
- Image {
- anchors.centerIn: parent
- source: checkBox.checked ? checkBox.checkedIcon :
- checkBox.uncheckedIcon
+ RowLayout {
+ Layout.fillWidth: true
+ Rectangle {
+ anchors.left: parent.left
+ width: 25 * scaleRatio
+ height: checkBox.height - 1
+ //radius: 4
+ y: 0
+ color: "#DBDBDB"
}
- }
- Text {
- id: label
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: 25 + 12
- font.family: "Arial"
- font.pixelSize: checkBox.fontSize
- color: "#525252"
- }
+ Rectangle {
+ id: backgroundRect
+ anchors.left: parent.left
+ width: 25 * scaleRatio
+ height: checkBox.height - 1
+ //radius: 4
+ y: 1
+ color: "#FFFFFF"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- checkBox.checked = !checkBox.checked
- checkBox.clicked()
+ Image {
+ anchors.centerIn: parent
+ source: checkBox.checked ? checkBox.checkedIcon :
+ checkBox.uncheckedIcon
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ toggle()
+ }
+ }
+ }
+
+ Text {
+ id: label
+ font.family: "Arial"
+ font.pixelSize: checkBox.fontSize
+ color: "#525252"
+ wrapMode: Text.Wrap
+ Layout.fillWidth: true
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ toggle()
+ }
+ }
}
}
}
diff --git a/components/DaemonManagerDialog.qml b/components/DaemonManagerDialog.qml
index 77908b1f..009787eb 100644
--- a/components/DaemonManagerDialog.qml
+++ b/components/DaemonManagerDialog.qml
@@ -90,7 +90,7 @@ Window {
}
Text {
- text: qsTr("Starting Monero daemon in %1 seconds").arg(countDown);
+ text: qsTr("Starting local node in %1 seconds").arg(countDown);
font.pixelSize: 18
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml
index 082822d3..d8024d18 100644
--- a/components/HistoryTable.qml
+++ b/components/HistoryTable.qml
@@ -79,14 +79,6 @@ ListView {
}
}
- StandardDialog {
- id: detailsPopup
- cancelVisible: false
- okVisible: true
- width:850
- }
-
-
delegate: Rectangle {
id: delegate
height: 144
@@ -111,10 +103,10 @@ ListView {
onClicked: {
var tx_key = currentWallet.getTxKey(hash)
var tx_note = currentWallet.getUserNote(hash)
- detailsPopup.title = "Transaction details";
- detailsPopup.content = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations);
- detailsPopup.open();
-
+ informationPopup.title = "Transaction details";
+ informationPopup.content = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations);
+ informationPopup.onCloseCallback = null
+ informationPopup.open();
}
}
@@ -383,7 +375,7 @@ ListView {
Column {
anchors.top: parent.top
width: 148
- visible: isOut
+ visible: isOut && fee != ""
Text {
anchors.left: parent.left
font.family: "Arial"
diff --git a/components/HistoryTableMobile.qml b/components/HistoryTableMobile.qml
new file mode 100644
index 00000000..87545755
--- /dev/null
+++ b/components/HistoryTableMobile.qml
@@ -0,0 +1,191 @@
+// 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.Layouts 1.1
+import moneroComponents.Clipboard 1.0
+import moneroComponents.AddressBookModel 1.0
+
+ListView {
+ id: listView
+ clip: true
+ boundsBehavior: ListView.StopAtBounds
+ property var previousItem
+ property var addressBookModel: null
+
+ function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations) {
+ var trStart = '
| ',
+ trMiddle = ' | ',
+ trEnd = " |
";
+
+ return ''
+ + (tx_id ? trStart + qsTr("Tx ID:") + trMiddle + tx_id + trEnd : "")
+ + (paymentId ? trStart + qsTr("Payment ID:") + trMiddle + paymentId + trEnd : "")
+ + (tx_key ? trStart + qsTr("Tx key:") + trMiddle + tx_key + trEnd : "")
+ + (tx_note ? trStart + qsTr("Tx note:") + trMiddle + tx_note + trEnd : "")
+ + (destinations ? trStart + qsTr("Destinations:") + trMiddle + destinations + trEnd : "")
+ + "
"
+ + translationManager.emptyString;
+ }
+
+ function lookupPaymentID(paymentId) {
+ if (!addressBookModel)
+ return ""
+ var idx = addressBookModel.lookupPaymentID(paymentId)
+ if (idx < 0)
+ return ""
+ idx = addressBookModel.index(idx, 0)
+ return addressBookModel.data(idx, AddressBookModel.AddressBookDescriptionRole)
+ }
+
+
+ footer: Rectangle {
+ height: 127 * scaleRatio
+ width: listView.width
+ color: "#FFFFFF"
+
+ Text {
+ anchors.centerIn: parent
+ font.family: "Arial"
+ font.pixelSize: 14 * scaleRatio
+ color: "#545454"
+ text: qsTr("No more results") + translationManager.emptyString
+ }
+ }
+
+ delegate: Rectangle {
+ id: delegate
+ height: tableContent.height + 20 * scaleRatio
+ width: listView.width
+ color: index % 2 ? "#F8F8F8" : "#FFFFFF"
+ Layout.leftMargin: 10 * scaleRatio
+ z: listView.count - index
+ function collapseDropdown() { dropdown.expanded = false }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ var tx_key = currentWallet.getTxKey(hash)
+ var tx_note = currentWallet.getUserNote(hash)
+
+ informationPopup.title = "Transaction details";
+ informationPopup.text = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations);
+ informationPopup.open();
+ informationPopup.onCloseCallback = null
+ }
+ }
+
+ Rectangle {
+ anchors.right: parent.right
+ anchors.rightMargin: 15 * scaleRatio
+ anchors.top: parent.top
+ anchors.topMargin: parent.height/2 - this.height/2
+ width: 30 * scaleRatio; height: 30 * scaleRatio
+ radius: 25
+ color: "#FF4304"
+
+ Image {
+ width: 20 * scaleRatio
+ height: 20 * scaleRatio
+ fillMode: Image.PreserveAspectFit
+ anchors.centerIn: parent
+ source: "qrc:///images/nextPage.png"
+ }
+ }
+
+ ColumnLayout {
+ id: tableContent
+ // Date
+ RowLayout {
+ Layout.topMargin: 20 * scaleRatio
+ Layout.leftMargin: 10 * scaleRatio
+ Text {
+ font.family: "Arial"
+ font.pixelSize: 14 * scaleRatio
+ color: "#555555"
+ text: date
+ }
+
+ Text {
+ font.family: "Arial"
+ font.pixelSize: 14 * scaleRatio
+ color: "#555555"
+ text: time
+ }
+
+ // Show confirmations
+ Text {
+ visible: confirmations < confirmationsRequired || isPending
+ Layout.leftMargin: 5 * scaleRatio
+ font.family: "Arial"
+ font.pixelSize: 14 * scaleRatio
+ color: (confirmations < confirmationsRequired)? "#FF6C3C" : "#545454"
+ text: {
+ if (!isPending)
+ if(confirmations < confirmationsRequired)
+ return qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired)
+ if (!isOut)
+ return qsTr("UNCONFIRMED") + translationManager.emptyString
+ return qsTr("PENDING") + translationManager.emptyString
+
+ }
+ }
+ }
+
+
+ // Amount & confirmations
+ RowLayout {
+ Layout.leftMargin: 10 * scaleRatio
+ spacing: 2
+ Text {
+ font.family: "Arial"
+ font.pixelSize: 14 * scaleRatio
+ color: isOut ? "#FF4F41" : "#36B05B"
+ text: isOut ? "↓" : "↑"
+ }
+
+ Text {
+ id: amountText
+ font.family: "Arial"
+ font.pixelSize: 18 * scaleRatio
+ color: isOut ? "#FF4F41" : "#36B05B"
+ text: displayAmount
+ }
+ }
+ }
+ }
+
+ ListModel {
+ id: dropModel
+ ListElement { name: "Copy address to clipboard"; icon: "../images/dropdownCopy.png" }
+ ListElement { name: "Add to address book"; icon: "../images/dropdownAdd.png" }
+ ListElement { name: "Send to this address"; icon: "../images/dropdownSend.png" }
+ ListElement { name: "Find similar transactions"; icon: "../images/dropdownSearch.png" }
+ }
+
+ Clipboard { id: clipboard }
+}
diff --git a/components/Input.qml b/components/Input.qml
index 78bec8ea..1390ca17 100644
--- a/components/Input.qml
+++ b/components/Input.qml
@@ -33,7 +33,7 @@ import QtQuick 2.2
TextField {
font.family: "Arial"
horizontalAlignment: TextInput.AlignLeft
-
+ selectByMouse: true
style: TextFieldStyle {
textColor: "#3F3F3F"
placeholderTextColor: "#BABABA"
diff --git a/components/Label.qml b/components/Label.qml
index 30ff3d33..ac5c92ec 100644
--- a/components/Label.qml
+++ b/components/Label.qml
@@ -35,19 +35,21 @@ Item {
property alias color: label.color
property alias textFormat: label.textFormat
property string tipText: ""
- property int fontSize: 12
+ property int fontSize: 16 * scaleRatio
property alias wrapMode: label.wrapMode
+ property alias horizontalAlignment: label.horizontalAlignment
signal linkActivated()
- width: icon.x + icon.width
- height: icon.height
+ width: icon.x + icon.width * scaleRatio
+ height: icon.height * scaleRatio
+ Layout.topMargin: 10 * scaleRatio
Text {
id: label
anchors.bottom: parent.bottom
- anchors.bottomMargin: 2
+ anchors.bottomMargin: 2 * scaleRatio
anchors.left: parent.left
font.family: "Arial"
- font.pixelSize: parent.fontSize
+ font.pixelSize: fontSize
color: "#555555"
onLinkActivated: item.linkActivated()
}
@@ -56,7 +58,7 @@ Item {
id: icon
anchors.verticalCenter: parent.verticalCenter
anchors.left: label.right
- anchors.leftMargin: 5
+ anchors.leftMargin: 5 * scaleRatio
source: "../images/whatIsIcon.png"
visible: appWindow.whatIsEnable
}
diff --git a/components/LineEdit.qml b/components/LineEdit.qml
index 3760fd2a..f7cb0612 100644
--- a/components/LineEdit.qml
+++ b/components/LineEdit.qml
@@ -36,13 +36,13 @@ Item {
property alias readOnly : input.readOnly
property alias cursorPosition: input.cursorPosition
property alias echoMode: input.echoMode
- property int fontSize: 18
+ property int fontSize: 18 * scaleRatio
property bool error: false
signal editingFinished()
signal accepted();
signal textUpdated();
- height: 37
+ height: 37 * scaleRatio
function getColor(error) {
if (error)
@@ -53,14 +53,14 @@ Item {
Rectangle {
anchors.fill: parent
- anchors.bottomMargin: 1
+ anchors.bottomMargin: 1 * scaleRatio
color: "#DBDBDB"
//radius: 4
}
Rectangle {
anchors.fill: parent
- anchors.topMargin: 1
+ anchors.topMargin: 1 * scaleRatio
color: getColor(error)
//radius: 4
}
@@ -68,8 +68,8 @@ Item {
Input {
id: input
anchors.fill: parent
- anchors.leftMargin: 4
- anchors.rightMargin: 30
+ anchors.leftMargin: 4 * scaleRatio
+ anchors.rightMargin: 30 * scaleRatio
font.pixelSize: parent.fontSize
onEditingFinished: item.editingFinished()
onAccepted: item.accepted();
diff --git a/components/MenuButton.qml b/components/MenuButton.qml
index a7baa019..23ab4f74 100644
--- a/components/MenuButton.qml
+++ b/components/MenuButton.qml
@@ -38,11 +38,18 @@ Rectangle {
property var under: null
signal clicked()
+ function doClick() {
+ // Android workaround
+ releaseFocus();
+ clicked();
+ }
+
+
function getOffset() {
var offset = 0
var item = button
while (item.under) {
- offset += 20
+ offset += 20 * scaleRatio
item = item.under
}
return offset
@@ -50,7 +57,7 @@ Rectangle {
color: checked ? "#FFFFFF" : "#1C1C1C"
property bool present: !under || under.checked || checked || under.numSelectedChildren > 0
- height: present ? ((appWindow.height >= 800) ? 64 : 52) : 0
+ height: present ? ((appWindow.height >= 800) ? 64 * scaleRatio : 52 * scaleRatio ) : 0
transform: Scale {
yScale: button.present ? 1 : 0
@@ -76,18 +83,18 @@ Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: parent.getOffset()
- width: 50
+ width: 50 * scaleRatio
Rectangle {
id: dot
anchors.centerIn: parent
- width: 16
+ width: 16 * scaleRatio
height: width
radius: height / 2
Rectangle {
anchors.centerIn: parent
- width: 12
+ width: 12 * scaleRatio
height: width
radius: height / 2
color: "#1C1C1C"
@@ -98,7 +105,7 @@ Rectangle {
Text {
id: symbolText
anchors.centerIn: parent
- font.pixelSize: 11
+ font.pixelSize: 11 * scaleRatio
font.bold: true
color: button.checked || buttonArea.containsMouse ? "#FFFFFF" : dot.color
visible: appWindow.ctrlPressed
@@ -117,7 +124,7 @@ Rectangle {
Image {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
- anchors.rightMargin: 20
+ anchors.rightMargin: 20 * scaleRatio
anchors.leftMargin: parent.getOffset()
source: "../images/menuIndicator.png"
}
@@ -126,9 +133,9 @@ Rectangle {
id: label
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
- anchors.leftMargin: parent.getOffset() + 50
+ anchors.leftMargin: parent.getOffset() + 50 * scaleRatio
font.family: "Arial"
- font.pixelSize: 18
+ font.pixelSize: 18 * scaleRatio
color: parent.checked ? "#000000" : "#FFFFFF"
}
@@ -139,7 +146,7 @@ Rectangle {
onClicked: {
if(parent.checked)
return
- button.clicked()
+ button.doClick()
parent.checked = true
}
}
diff --git a/components/MobileHeader.qml b/components/MobileHeader.qml
index 73b22430..0cd9c5e6 100644
--- a/components/MobileHeader.qml
+++ b/components/MobileHeader.qml
@@ -10,17 +10,16 @@ Rectangle {
anchors.leftMargin: 1
anchors.rightMargin: 1
Layout.fillWidth: true
- Layout.preferredHeight: 64
+ Layout.preferredHeight: 64 * scaleRatio
color: "#FFFFFF"
-// visible: basicMode
Image {
id: logo
- visible: appWindow.width > 460
+ visible: appWindow.width > 460 * scaleRatio
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -5
anchors.left: parent.left
- anchors.leftMargin: appWindow.persistentSettings.customDecorations ? 20 : 40
+ anchors.leftMargin: 50 * scaleRatio
source: "../images/moneroLogo2.png"
}
@@ -28,9 +27,8 @@ Rectangle {
id: icon
visible: !logo.visible
anchors.verticalCenter: parent.verticalCenter
-// anchors.verticalCenterOffset: -5
anchors.left: parent.left
- anchors.leftMargin: appWindow.persistentSettings.customDecorations ? 20 : 40
+ anchors.leftMargin: 40 * scaleRatio
source: "../images/moneroIcon.png"
}
@@ -38,16 +36,16 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
anchors.top: parent.top
anchors.right: parent.right
- anchors.topMargin: 10
- width: 256
+ anchors.topMargin: 10 * scaleRatio
+ width: 256 * scaleRatio
columns: 3
Text {
id: balanceLabel
- width: 116
- height: 20
+ width: 116 * scaleRatio
+ height: 20 * scaleRatio
font.family: "Arial"
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
@@ -58,10 +56,10 @@ Rectangle {
Text {
id: balanceText
- width: 110
- height: 20
+ width: 110 * scaleRatio
+ height: 20 * scaleRatio
font.family: "Arial"
- font.pixelSize: 18
+ font.pixelSize: 18 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
@@ -71,8 +69,8 @@ Rectangle {
}
Item {
- height: 20
- width: 20
+ height: 20 * scaleRatio
+ width: 20 * scaleRatio
Image {
anchors.verticalCenter: parent.verticalCenter
@@ -82,10 +80,10 @@ Rectangle {
}
Text {
- width: 116
- height: 20
+ width: 116 * scaleRatio
+ height: 20 * scaleRatio
font.family: "Arial"
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
@@ -96,10 +94,10 @@ Rectangle {
Text {
id: availableBalanceText
- width: 110
- height: 20
+ width: 110 * scaleRatio
+ height: 20 * scaleRatio
font.family: "Arial"
- font.pixelSize: 14
+ font.pixelSize: 14 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
diff --git a/components/NetworkStatusItem.qml b/components/NetworkStatusItem.qml
index 5ba77585..7e6a5d1d 100644
--- a/components/NetworkStatusItem.qml
+++ b/components/NetworkStatusItem.qml
@@ -29,7 +29,7 @@
import QtQuick 2.0
import moneroComponents.Wallet 1.0
-Row {
+Rectangle {
id: item
property var connected: Wallet.ConnectionStatus_Disconnected
@@ -51,6 +51,8 @@ Row {
if (status == Wallet.ConnectionStatus_Connected) {
if(!appWindow.daemonSynced)
return qsTr("Synchronizing")
+ if(appWindow.remoteNodeConnected)
+ return qsTr("Remote node")
return qsTr("Connected")
}
if (status == Wallet.ConnectionStatus_WrongVersion)
@@ -60,37 +62,44 @@ Row {
return qsTr("Invalid connection status")
}
- Item {
- id: iconItem
- anchors.bottom: parent.bottom
- width: 50
- height: 50
- Image {
- anchors.centerIn: parent
- source: getConnectionStatusImage(item.connected)
+ color: "#1C1C1C"
+ Row {
+ height: 60 * scaleRatio
+ Item {
+ id: iconItem
+ anchors.bottom: parent.bottom
+ width: 50 * scaleRatio
+ height: 50 * scaleRatio
+
+ Image {
+ anchors.centerIn: parent
+ source: getConnectionStatusImage(item.connected)
+ }
+ }
+
+ Column {
+ anchors.bottom: parent.bottom
+ height: 53 * scaleRatio
+ spacing: 3 * scaleRatio
+
+ Text {
+ anchors.left: parent.left
+ font.family: "Arial"
+ font.pixelSize: 12 * scaleRatio
+ color: "#545454"
+ text: qsTr("Network status") + translationManager.emptyString
+ }
+
+ Text {
+ anchors.left: parent.left
+ font.family: "Arial"
+ font.pixelSize: 18 * scaleRatio
+ color: getConnectionStatusColor(item.connected)
+ text: getConnectionStatusString(item.connected) + translationManager.emptyString
+ }
}
}
- Column {
- anchors.bottom: parent.bottom
- height: 53
- spacing: 3
- Text {
- anchors.left: parent.left
- font.family: "Arial"
- font.pixelSize: 12
- color: "#545454"
- text: qsTr("Network status") + translationManager.emptyString
- }
-
- Text {
- anchors.left: parent.left
- font.family: "Arial"
- font.pixelSize: 18
- color: getConnectionStatusColor(item.connected)
- text: getConnectionStatusString(item.connected) + translationManager.emptyString
- }
- }
}
diff --git a/components/PasswordDialog.qml b/components/PasswordDialog.qml
index db9654cb..b90e192b 100644
--- a/components/PasswordDialog.qml
+++ b/components/PasswordDialog.qml
@@ -35,40 +35,48 @@ import QtQuick.Window 2.0
import "../components" as MoneroComponents
-Window {
+Item {
id: root
- modality: Qt.ApplicationModal
- flags: Qt.Window | Qt.FramelessWindowHint
+ visible: false
+ Rectangle {
+ id: bg
+ z: parent.z + 1
+ anchors.fill: parent
+ color: "white"
+ opacity: 0.9
+ }
+
property alias password: passwordInput.text
property string walletName
// same signals as Dialog has
signal accepted()
signal rejected()
-
+ signal closeCallback()
function open(walletName) {
root.walletName = walletName ? walletName : ""
+ leftPanel.enabled = false
+ middlePanel.enabled = false
+ titleBar.enabled = false
show()
+ root.visible = true;
+ passwordInput.focus = true
}
- // TODO: implement without hardcoding sizes
- width: 480
- height: walletName ? 240 : 200
-
- // Make window draggable
- MouseArea {
- anchors.fill: parent
- property point lastMousePos: Qt.point(0, 0)
- onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
- onMouseXChanged: root.x += (mouseX - lastMousePos.x)
- onMouseYChanged: root.y += (mouseY - lastMousePos.y)
+ function close() {
+ leftPanel.enabled = true
+ middlePanel.enabled = true
+ titleBar.enabled = true
+ root.visible = false;
+ closeCallback();
}
ColumnLayout {
+ z: bg.z + 1
id: mainLayout
spacing: 10
- anchors { fill: parent; margins: 35 }
+ anchors { fill: parent; margins: 35 * scaleRatio }
ColumnLayout {
id: column
@@ -81,20 +89,20 @@ Window {
Layout.columnSpan: 2
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
- font.pixelSize: 24
+ font.pixelSize: 18 * scaleRatio
font.family: "Arial"
color: "#555555"
}
TextField {
id : passwordInput
- focus: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
+ Layout.maximumWidth: 400 * scaleRatio
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
font.family: "Arial"
- font.pixelSize: 32
+ font.pixelSize: 32 * scaleRatio
echoMode: TextInput.Password
KeyNavigation.tab: okButton
@@ -128,27 +136,18 @@ Window {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
anchors.bottomMargin: 3
+ Layout.maximumWidth: passwordInput.width
}
- // padding
- Rectangle {
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignHCenter
- height: 10
- opacity: 0
- color: "black"
- }
}
// Ok/Cancel buttons
RowLayout {
id: buttons
- spacing: 60
+ spacing: 60 * scaleRatio
Layout.alignment: Qt.AlignHCenter
MoneroComponents.StandardButton {
id: cancelButton
- width: 120
- fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -162,13 +161,11 @@ Window {
}
MoneroComponents.StandardButton {
id: okButton
- width: 120
- fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
- text: qsTr("Ok")
+ text: qsTr("Continue")
KeyNavigation.tab: cancelButton
onClicked: {
root.close()
@@ -178,6 +175,3 @@ Window {
}
}
}
-
-
-
diff --git a/components/ProcessingSplash.qml b/components/ProcessingSplash.qml
index 2f6725db..d7fbd5cb 100644
--- a/components/ProcessingSplash.qml
+++ b/components/ProcessingSplash.qml
@@ -31,17 +31,26 @@ import QtQuick.Window 2.1
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
-Window {
+Rectangle {
id: root
- modality: Qt.ApplicationModal
- flags: Qt.Window
+ color: "white"
+ visible: false
+ z:11
property alias messageText: messageTitle.text
property alias heightProgressText : heightProgress.text
- width: 200
- height: 100
+ width: 200 * scaleRatio
+ height: 100 * scaleRatio
opacity: 0.7
+ function show() {
+ root.visible = true;
+ }
+
+ function close() {
+ root.visible = false;
+ }
+
ColumnLayout {
id: rootLayout
@@ -49,8 +58,8 @@ Window {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: 30
- anchors.rightMargin: 30
+ anchors.leftMargin: 30 * scaleRatio
+ anchors.rightMargin: 30 * scaleRatio
BusyIndicator {
running: parent.visible
@@ -61,7 +70,7 @@ Window {
id: messageTitle
text: "Please wait..."
font {
- pixelSize: 22
+ pixelSize: 22 * scaleRatio
}
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
@@ -72,7 +81,7 @@ Window {
Text {
id: heightProgress
font {
- pixelSize: 18
+ pixelSize: 18 * scaleRatio
}
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
diff --git a/components/ProgressBar.qml b/components/ProgressBar.qml
index 0c1519de..8f462122 100644
--- a/components/ProgressBar.qml
+++ b/components/ProgressBar.qml
@@ -29,15 +29,13 @@
import QtQuick 2.0
import moneroComponents.Wallet 1.0
-Item {
+Rectangle {
id: item
property int fillLevel: 0
- height: 22
- anchors.margins:15
visible: false
- //clip: true
+ color: "#1C1C1C"
- function updateProgress(currentBlock,targetBlock, blocksToSync){
+ function updateProgress(currentBlock,targetBlock, blocksToSync, statusTxt){
if(targetBlock == 1) {
fillLevel = 0
progressText.text = qsTr("Establishing connection...");
@@ -54,53 +52,68 @@ Item {
else
var progressLevel = (100*(currentBlock/targetBlock)).toFixed(0);
fillLevel = progressLevel
- progressText.text = qsTr("Blocks remaining: %1").arg(remaining.toFixed(0));
+ if(typeof statusTxt != "undefined" && statusTxt != "") {
+ progressText.text = statusTxt + (" %1").arg(remaining.toFixed(0));
+ } else {
+ progressText.text = qsTr("Blocks remaining: %1").arg(remaining.toFixed(0));
+ }
+
+
+
progressBar.visible = currentBlock < targetBlock
}
}
- Rectangle {
- id: bar
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- height: 22
- radius: 2
- color: "#FFFFFF"
-
+ Item {
+ anchors.leftMargin: 15 * scaleRatio
+ anchors.rightMargin: 15 * scaleRatio
+ anchors.fill: parent
Rectangle {
- id: fillRect
+ id: bar
+ anchors.left: parent.left
+ anchors.right: parent.right
anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.margins: 2
- height: bar.height
- property int maxWidth: parent.width - 4
- width: (maxWidth * fillLevel) / 100
- color: {
- if(item.fillLevel < 99 ) return "#FF6C3C"
- //if(item.fillLevel < 99) return "#FFE00A"
- return "#36B25C"
- }
+ height: 22 * scaleRatio
+ radius: 2 * scaleRatio
+ color: "#FFFFFF"
- }
-
- Rectangle {
- color:"#333"
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.leftMargin: 8
-
- Text {
- id:progressText
+ Rectangle {
+ id: fillRect
+ anchors.top: parent.top
anchors.bottom: parent.bottom
- font.family: "Arial"
- font.pixelSize: 12
- color: "#000"
- text: qsTr("Synchronizing blocks")
- height:18
+ anchors.left: parent.left
+ anchors.margins: 2 * scaleRatio
+ height: bar.height
+ property int maxWidth: parent.width - 4 * scaleRatio
+ width: (maxWidth * fillLevel) / 100
+ color: {
+ if(item.fillLevel < 99 ) return "#FF6C3C"
+ //if(item.fillLevel < 99) return "#FFE00A"
+ return "#36B25C"
+ }
+
+ }
+
+ Rectangle {
+ color:"#333"
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: 8 * scaleRatio
+
+ Text {
+ id:progressText
+ anchors.bottom: parent.bottom
+ font.family: "Arial"
+ font.pixelSize: 12 * scaleRatio
+ color: "#000"
+ text: qsTr("Synchronizing blocks")
+ height:18 * scaleRatio
+ }
}
}
+
}
+
+
}
diff --git a/components/QRCodeScanner.qml b/components/QRCodeScanner.qml
index d9a6d933..669bd271 100644
--- a/components/QRCodeScanner.qml
+++ b/components/QRCodeScanner.qml
@@ -44,7 +44,7 @@ Rectangle {
color: "black"
state: "Stopped"
- signal qrcode_decoded(string address, string payment_id, string amount, string tx_description, string recipient_name)
+ signal qrcode_decoded(string address, string payment_id, string amount, string tx_description, string recipient_name, var extra_parameters)
states: [
State {
@@ -83,7 +83,7 @@ Rectangle {
id : finder
objectName: "QrFinder"
onDecoded : {
- root.qrcode_decoded(address, payment_id, amount, tx_description, recipient_name)
+ root.qrcode_decoded(address, payment_id, amount, tx_description, recipient_name, extra_parameters)
root.state = "Stopped"
}
onNotifyError : {
@@ -126,7 +126,7 @@ Rectangle {
MessageDialog {
id: messageDialog
- title: "Scanning QrCode"
+ title: qsTr("QrCode Scanned") + translationManager.emptyString
onAccepted: {
root.state = "Stopped"
}
diff --git a/components/RemoteNodeEdit.qml b/components/RemoteNodeEdit.qml
new file mode 100644
index 00000000..83b059cd
--- /dev/null
+++ b/components/RemoteNodeEdit.qml
@@ -0,0 +1,60 @@
+// 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.Controls 1.2
+import QtQuick.Controls.Styles 1.2
+import QtQuick 2.2
+import QtQuick.Layouts 1.1
+
+GridLayout {
+ columns: (isMobile) ? 1 : 2
+ id: root
+ property alias daemonAddrText: daemonAddr.text
+ property alias daemonPortText: daemonPort.text
+
+ signal editingFinished()
+
+ function getAddress() {
+ return daemonAddr.text.trim() + ":" + daemonPort.text.trim()
+ }
+
+ LineEdit {
+ id: daemonAddr
+ Layout.fillWidth: true
+ placeholderText: qsTr("Remote Node Hostname / IP") + translationManager.emptyString
+ onEditingFinished: root.editingFinished()
+ }
+
+
+ LineEdit {
+ id: daemonPort
+ Layout.fillWidth: true
+ placeholderText: qsTr("Port") + translationManager.emptyString
+ onEditingFinished: root.editingFinished()
+ }
+}
diff --git a/components/StandardButton.qml b/components/StandardButton.qml
index 33cedee7..6f714947 100644
--- a/components/StandardButton.qml
+++ b/components/StandardButton.qml
@@ -31,19 +31,25 @@ import QtQuick.Layouts 1.1
Item {
id: button
- height: 37
- property string shadowPressedColor
- property string shadowReleasedColor
- property string pressedColor
- property string releasedColor
+ height: 37 * scaleRatio
+ property string shadowPressedColor: "#B32D00"
+ property string shadowReleasedColor: "#FF4304"
+ property string pressedColor: "#FF4304"
+ property string releasedColor: "#FF6C3C"
property string icon: ""
property string textColor: "#FFFFFF"
- property int fontSize: 12
+ property int fontSize: 12 * scaleRatio
property alias text: label.text
signal clicked()
// Dynamic label width
- Layout.minimumWidth: (label.contentWidth > 80)? label.contentWidth + 20 : 100
+ Layout.minimumWidth: (label.contentWidth > 50)? label.contentWidth + 10 : 60
+
+ function doClick() {
+ // Android workaround
+ releaseFocus();
+ clicked();
+ }
Rectangle {
anchors.left: parent.left
@@ -98,9 +104,9 @@ Item {
MouseArea {
id: buttonArea
anchors.fill: parent
- onClicked: parent.clicked()
+ onClicked: doClick()
}
- Keys.onSpacePressed: clicked()
- Keys.onReturnPressed: clicked()
+ Keys.onSpacePressed: doClick()
+ Keys.onReturnPressed: doClick()
}
diff --git a/components/StandardDialog.qml b/components/StandardDialog.qml
index 681c2d3d..84402147 100644
--- a/components/StandardDialog.qml
+++ b/components/StandardDialog.qml
@@ -35,10 +35,10 @@ import QtQuick.Window 2.0
import "../components" as MoneroComponents
-Window {
+Rectangle {
id: root
- modality: Qt.ApplicationModal
- flags: Qt.Window | Qt.FramelessWindowHint
+ color: "white"
+ visible: false
property alias title: dialogTitle.text
property alias text: dialogContent.text
property alias content: root.text
@@ -53,6 +53,7 @@ Window {
// same signals as Dialog has
signal accepted()
signal rejected()
+ signal closeCallback();
// Make window draggable
MouseArea {
@@ -64,12 +65,24 @@ Window {
}
function open() {
+ // Center
+ if(!isMobile) {
+ root.x = parent.width/2 - root.width/2
+ root.y = screenHeight/2 - root.height/2
+ }
show()
+ root.z = 11
+ root.visible = true;
+ }
+
+ function close() {
+ root.visible = false;
+ closeCallback();
}
// TODO: implement without hardcoding sizes
- width: 480
- height: 280
+ width: isMobile ? screenWidth : 480
+ height: isMobile ? screenHeight : 280
ColumnLayout {
id: mainLayout
@@ -84,7 +97,7 @@ Window {
Label {
id: dialogTitle
horizontalAlignment: Text.AlignHCenter
- font.pixelSize: 32
+ font.pixelSize: 18 * scaleRatio
font.family: "Arial"
color: "#555555"
}
@@ -99,7 +112,23 @@ Window {
font.family: "Arial"
textFormat: TextEdit.AutoText
readOnly: true
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
+ selectByMouse: false
+ wrapMode: TextEdit.Wrap
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ appWindow.showStatusMessage(qsTr("Double tap to copy"),3)
+ }
+ onDoubleClicked: {
+ parent.selectAll()
+ parent.copy()
+ parent.deselect()
+ console.log("copied to clipboard");
+ appWindow.showStatusMessage(qsTr("Content copied to clipboard"),3)
+ }
+ }
}
}
@@ -111,8 +140,6 @@ Window {
MoneroComponents.StandardButton {
id: cancelButton
- width: 120
- fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -126,13 +153,11 @@ Window {
MoneroComponents.StandardButton {
id: okButton
- width: 120
- fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
- text: qsTr("Ok")
+ text: qsTr("OK")
KeyNavigation.tab: cancelButton
onClicked: {
root.close()
diff --git a/components/StandardDropdown.qml b/components/StandardDropdown.qml
index 50b60fe0..5aac249b 100644
--- a/components/StandardDropdown.qml
+++ b/components/StandardDropdown.qml
@@ -38,7 +38,10 @@ Item {
property string textColor: "#FFFFFF"
property alias currentIndex: column.currentIndex
property bool expanded: false
- height: 37
+
+ signal changed();
+
+ height: 37 * scaleRatio
onExpandedChanged: if(expanded) appWindow.currentItem = dropdown
function hide() { dropdown.expanded = false }
@@ -54,12 +57,18 @@ Item {
return true
}
+ // Workaroud for suspected memory leak in 5.8 causing malloc crash on app exit
+ function update() {
+ firstColText.text = column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column1) + translationManager.emptyString : ""
+ secondColText.text = column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column2) + translationManager.emptyString : ""
+ }
+
Item {
id: head
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
- height: 37
+ height: 37 * scaleRatio
Rectangle {
anchors.left: parent.left
@@ -82,8 +91,8 @@ Item {
Rectangle {
anchors.left: parent.left
anchors.bottom: parent.bottom
- height: 3
- width: 3
+ height: 3 * scaleRatio
+ width: 3 * scaleRatio
color: dropdown.pressedColor
visible: dropdown.expanded || droplist.height > 0
}
@@ -91,8 +100,8 @@ Item {
Rectangle {
anchors.right: parent.right
anchors.bottom: parent.bottom
- height: 3
- width: 3
+ height: 3 * scaleRatio
+ width: 3 * scaleRatio
color: dropdown.pressedColor
visible: dropdown.expanded || droplist.height > 0
}
@@ -101,26 +110,23 @@ Item {
id: firstColText
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
- anchors.leftMargin: 12
+ anchors.leftMargin: 12 * scaleRatio
elide: Text.ElideRight
font.family: "Arial"
font.bold: true
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
- text: column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column1) + translationManager.emptyString : ""
}
Text {
id: secondColText
anchors.verticalCenter: parent.verticalCenter
anchors.right: separator.left
- anchors.rightMargin: 12
+ anchors.rightMargin: 12 * scaleRatio
width: dropdown.expanded ? w : (separator.x - 12) - (firstColText.x + firstColText.width + 5)
font.family: "Arial"
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
- text: column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column2) + translationManager.emptyString : ""
-
property int w: 0
Component.onCompleted: w = implicitWidth
}
@@ -129,7 +135,7 @@ Item {
id: separator
anchors.right: dropIndicator.left
anchors.verticalCenter: parent.verticalCenter
- height: 18
+ height: 18 * scaleRatio
width: 1
color: "#FFFFFF"
}
@@ -139,12 +145,12 @@ Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
- width: 32
+ width: 32 * scaleRatio
Image {
anchors.centerIn: parent
source: "../images/whiteDropIndicator.png"
- rotation: dropdown.expanded ? 180 : 0
+ rotation: dropdown.expanded ? 180 * scaleRatio : 0
}
}
@@ -168,14 +174,14 @@ Item {
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
- width: 3; height: 3
+ width: 3 * scaleRatio; height: 3 * scaleRatio
color: dropdown.pressedColor
}
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
- width: 3; height: 3
+ width: 3 * scaleRatio; height: 3 * scaleRatio
color: dropdown.pressedColor
}
@@ -209,7 +215,7 @@ Item {
delegate: Rectangle {
anchors.left: parent.left
anchors.right: parent.right
- height: 30
+ height: 30 * scaleRatio
//radius: index === repeater.count - 1 ? 4 : 0
color: itemArea.containsMouse || index === column.currentIndex || itemArea.containsMouse ? dropdown.releasedColor : dropdown.pressedColor
@@ -217,11 +223,11 @@ Item {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: col2Text.left
- anchors.leftMargin: 12
- anchors.rightMargin: column2.length > 0 ? 12 : 0
+ anchors.leftMargin: 12 * scaleRatio
+ anchors.rightMargin: column2.length > 0 ? 12 * scaleRatio: 0
font.family: "Arial"
font.bold: true
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
text: qsTr(column1) + translationManager.emptyString
}
@@ -230,9 +236,9 @@ Item {
id: col2Text
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
- anchors.rightMargin: 45
+ anchors.rightMargin: 45 * scaleRatio
font.family: "Arial"
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
text: column2
}
@@ -240,14 +246,14 @@ Item {
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
- width: 3; height: 3
+ width: 3 * scaleRatio; height: 3 * scaleRatio
color: parent.color
}
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
- width: 3; height: 3
+ width: 3 * scaleRatio; height: 3 * scaleRatio
color: parent.color
}
@@ -258,6 +264,8 @@ Item {
onClicked: {
dropdown.expanded = false
column.currentIndex = index
+ changed();
+ dropdown.update()
}
}
}
diff --git a/components/TickDelegate.qml b/components/TickDelegate.qml
index 3b256a2d..4e9789a4 100644
--- a/components/TickDelegate.qml
+++ b/components/TickDelegate.qml
@@ -49,7 +49,7 @@ Item {
anchors.bottomMargin: 2
font.family: "Arial"
font.bold: true
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
color: "#4A4949"
text: {
if(currentIndex === 0) return qsTr("Normal") + translationManager.emptyString
diff --git a/components/TitleBar.qml b/components/TitleBar.qml
index 34f25e73..b8400273 100644
--- a/components/TitleBar.qml
+++ b/components/TitleBar.qml
@@ -28,6 +28,7 @@
import QtQuick 2.2
import QtQuick.Window 2.0
+import QtQuick.Layouts 1.1
Rectangle {
id: titleBar
@@ -37,7 +38,7 @@ Rectangle {
property alias basicButtonVisible: goToBasicVersionButton.visible
property bool customDecorations: true
signal goToBasicVersion(bool yes)
- height: customDecorations ? 30 : 0
+ height: customDecorations && !isMobile ? 30 : 0
y: -height
property string title
property alias maximizeButtonVisible: maximizeButton.visible
@@ -53,21 +54,22 @@ Rectangle {
}
Rectangle {
+
id: goToBasicVersionButton
property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width
property bool checked: false
anchors.top: parent.top
anchors.left: parent.left
- color: basicMouseArea.containsMouse || !leftPanel.visible ? "#FFE00A" : "#000000"
- height: 30
+ color: "#FFE00A"
+ height: 30 * scaleRatio
width: height
visible: isMobile
Image {
+ width: parent.width * 2/3;
+ height: width;
anchors.centerIn: parent
- rotation: !leftPanel.visible ? 180 : 0
- source: parent.customDecorations || !leftPanel.visible ? "../images/goToBasicVersionHovered.png" :
- "../images/gotoBasicVersion.png"
+ source: "../images/menu.png"
}
MouseArea {
@@ -75,6 +77,7 @@ Rectangle {
hoverEnabled: true
anchors.fill: parent
onClicked: {
+ releaseFocus()
parent.checked = !parent.checked
titleBar.goToBasicVersion(leftPanel.visible)
}
diff --git a/filter.cpp b/filter.cpp
index 9a2c9356..36f2c968 100644
--- a/filter.cpp
+++ b/filter.cpp
@@ -71,6 +71,12 @@ bool filter::eventFilter(QObject *obj, QEvent *ev) {
m_tabPressed = false;
QString sks;
+#ifdef Q_OS_ANDROID
+ if(ke->key() == Qt::Key_Back) {
+ qDebug() << "Android back hit";
+ sks = "android_back";
+ }
+#endif
if(ke->key() == Qt::Key_Control) {
sks = "Ctrl";
#ifdef Q_OS_MAC
diff --git a/images/menu.png b/images/menu.png
new file mode 100644
index 00000000..95378c69
Binary files /dev/null and b/images/menu.png differ
diff --git a/ios_get_libwallet.api.sh b/ios_get_libwallet.api.sh
index 3592829c..df07a98e 100755
--- a/ios_get_libwallet.api.sh
+++ b/ios_get_libwallet.api.sh
@@ -1,4 +1,12 @@
#!/bin/bash -e
+
+# 3 header files required by monero are missing from the IOS SDK. I copied them from iphoneSimulator SDK
+# cd /Applications/XCode.app
+# sudo cp ./Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/sys/vmmeter.h ./Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sys/
+# sudo cp ./Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/netinet/udp_var.h ./Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/netinet/
+# sudo cp ./Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/netinet/ip_var.h ./Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/netinet/
+
+
if [ -z $BUILD_TYPE ]; then
BUILD_TYPE=release
fi
@@ -18,17 +26,17 @@ if [ -z $OPENSSL_ROOT_DIR ]; then
fi
echo "Building IOS armv7"
-rm -r monero/build
+rm -r monero/build > /dev/null
mkdir -p monero/build/release
pushd monero/build/release
cmake -D IOS=ON -D ARCH=armv7 -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
make -j4 && make install
popd
echo "Building IOS arm64"
-rm -r monero/build
+rm -r monero/build > /dev/null
mkdir -p monero/build/release
pushd monero/build/release
-cmake -D IOS=ON -D ARCH=arm64 -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
+cmake -D IOS=ON -D ARCH=armv8-a -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
make -j4 && make install
popd
diff --git a/main.cpp b/main.cpp
index 1a9a979d..da9686dd 100644
--- a/main.cpp
+++ b/main.cpp
@@ -32,6 +32,8 @@
#include
#include
#include
+#include
+#include
#include "clipboardAdapter.h"
#include "filter.h"
#include "oscursor.h"
@@ -168,6 +170,7 @@ int main(int argc, char *argv[])
bool isWindows = false;
bool isIOS = false;
bool isMac = false;
+ bool isAndroid = false;
#ifdef Q_OS_WIN
isWindows = true;
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
@@ -180,9 +183,42 @@ int main(int argc, char *argv[])
#ifdef Q_OS_MAC
isMac = true;
#endif
+#ifdef Q_OS_ANDROID
+ isAndroid = true;
+#endif
engine.rootContext()->setContextProperty("isWindows", isWindows);
engine.rootContext()->setContextProperty("isIOS", isIOS);
+ engine.rootContext()->setContextProperty("isAndroid", isAndroid);
+
+ // screen settings
+ // Mobile is designed on 128dpi
+ qreal ref_dpi = 128;
+ QRect geo = QApplication::desktop()->availableGeometry();
+ QRect rect = QGuiApplication::primaryScreen()->geometry();
+ qreal height = qMax(rect.width(), rect.height());
+ qreal width = qMin(rect.width(), rect.height());
+ qreal dpi = QGuiApplication::primaryScreen()->logicalDotsPerInch();
+ qreal physicalDpi = QGuiApplication::primaryScreen()->physicalDotsPerInch();
+ qreal calculated_ratio = physicalDpi/ref_dpi;
+
+ engine.rootContext()->setContextProperty("screenWidth", geo.width());
+ engine.rootContext()->setContextProperty("screenHeight", geo.height());
+#ifdef Q_OS_ANDROID
+ engine.rootContext()->setContextProperty("scaleRatio", calculated_ratio);
+#else
+ engine.rootContext()->setContextProperty("scaleRatio", 1);
+#endif
+
+ qDebug() << "available width: " << geo.width();
+ qDebug() << "available height: " << geo.height();
+ qDebug() << "devicePixelRatio: " << app.devicePixelRatio();
+ qDebug() << "screen height: " << height;
+ qDebug() << "screen width: " << width;
+ qDebug() << "screen logical dpi: " << dpi;
+ qDebug() << "screen Physical dpi: " << physicalDpi;
+ qDebug() << "screen calculated ratio: " << calculated_ratio;
+
if (!moneroAccountsRootDir.empty()) {
QString moneroAccountsDir = moneroAccountsRootDir.at(0) + "/Monero/wallets";
diff --git a/main.qml b/main.qml
index 285423f3..c98e9efe 100644
--- a/main.qml
+++ b/main.qml
@@ -57,7 +57,7 @@ ApplicationWindow {
property bool isNewWallet: false
property int restoreHeight:0
property bool daemonSynced: false
- property int maxWindowHeight: (Screen.height < 900)? 720 : 800;
+ property int maxWindowHeight: (isAndroid || isIOS)? screenHeight : (screenHeight < 900)? 720 : 800;
property bool daemonRunning: false
property alias toolTip: toolTip
property string walletName
@@ -66,8 +66,14 @@ ApplicationWindow {
property int timeToUnlock: 0
property bool qrScannerEnabled: (typeof builtWithScanner != "undefined") && builtWithScanner
property int blocksToSync: 1
- property var isMobile: (appWindow.width > 700) ? false : true
+ property var isMobile: (appWindow.width > 700 && !isAndroid) ? false : true
property var cameraUi
+ property bool remoteNodeConnected: false
+ property bool androidCloseTapped: false;
+ // Default daemon addresses
+ readonly property string localDaemonAddress : !persistentSettings.testnet ? "localhost:18081" : "localhost:28081"
+ property string currentDaemonAddress;
+ property bool startLocalNodeCancelled: false
// true if wallet ever synchronized
property bool walletInitialized : false
@@ -164,7 +170,6 @@ ApplicationWindow {
function initialize() {
console.log("initializing..")
- walletInitialized = false;
// Use stored log level
if (persistentSettings.logLevel == 5)
@@ -186,7 +191,7 @@ ApplicationWindow {
console.log("Daemon change - closing " + currentWallet)
closeWallet();
currentWallet = undefined
- } else {
+ } else if (!walletInitialized) {
// set page to transfer if not changing daemon
middlePanel.state = "Transfer";
@@ -194,9 +199,13 @@ ApplicationWindow {
}
- walletManager.setDaemonAddress(persistentSettings.daemon_address)
+
+ // Local daemon settings
+ walletManager.setDaemonAddress(localDaemonAddress)
+
+
// wallet already opened with wizard, we just need to initialize it
- if (typeof wizard.settings['wallet'] !== 'undefined') {
+ if (typeof wizard.m_wallet !== 'undefined') {
console.log("using wizard wallet")
//Set restoreHeight
if(persistentSettings.restore_height > 0){
@@ -204,11 +213,11 @@ ApplicationWindow {
restoreHeight = persistentSettings.restore_height
}
- connectWallet(wizard.settings['wallet'])
+ connectWallet(wizard.m_wallet)
isNewWallet = true
// We don't need the wizard wallet any more - delete to avoid conflict with daemon adress change
- delete wizard.settings['wallet']
+ delete wizard.m_wallet
} else {
var wallet_path = walletPath();
if(isIOS)
@@ -236,12 +245,10 @@ ApplicationWindow {
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
middlePanel.checkPaymentClicked.disconnect(handleCheckPayment);
}
+
currentWallet = undefined;
- if (isIOS) {
- console.log("closing sync - ios")
- walletManager.closeWallet();
- } else
- walletManager.closeWalletAsync();
+ walletManager.closeWallet();
+
}
function connectWallet(wallet) {
@@ -270,14 +277,20 @@ ApplicationWindow {
middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable);
middlePanel.checkPaymentClicked.connect(handleCheckPayment);
- console.log("initializing with daemon address: ", persistentSettings.daemon_address)
+
console.log("Recovering from seed: ", persistentSettings.is_recovering)
console.log("restore Height", persistentSettings.restore_height)
// Use saved daemon rpc login settings
- currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
+ currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword)
- currentWallet.initAsync(persistentSettings.daemon_address, 0, persistentSettings.is_recovering, persistentSettings.restore_height);
+ if(persistentSettings.useRemoteNode)
+ currentDaemonAddress = persistentSettings.remoteNodeAddress
+ else
+ currentDaemonAddress = localDaemonAddress
+
+ console.log("initializing with daemon address: ", currentDaemonAddress)
+ currentWallet.initAsync(currentDaemonAddress, 0, persistentSettings.is_recovering, persistentSettings.restore_height);
}
function walletPath() {
@@ -302,7 +315,7 @@ ApplicationWindow {
middlePanel.transferView.updatePriorityDropdown();
// If wallet isnt connected and no daemon is running - Ask
- if(isDaemonLocal() && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.testnet)){
+ if(!isMobile && isDaemonLocal() && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.testnet)){
daemonManagerDialog.open();
}
// initialize transaction history once wallet is initialized first time;
@@ -358,10 +371,25 @@ ApplicationWindow {
console.log("New block found - updating history")
currentWallet.history.refresh()
timeToUnlock = currentWallet.history.minutesToUnlock
- leftPanel.minutesToUnlockTxt = (timeToUnlock > 0)? (timeToUnlock == 20)? qsTr("Unlocked balance (waiting for block)").arg(timeToUnlock) : qsTr("Unlocked balance (~%1 min)").arg(timeToUnlock) : qsTr("Unlocked balance");
+ leftPanel.minutesToUnlockTxt = (timeToUnlock > 0)? (timeToUnlock == 20)? qsTr("Unlocked balance (waiting for block)") : qsTr("Unlocked balance (~%1 min)").arg(timeToUnlock) : qsTr("Unlocked balance");
}
}
+ function connectRemoteNode() {
+ console.log("connecting remote node");
+ persistentSettings.useRemoteNode = true;
+ currentWallet.initAsync(persistentSettings.remoteNodeAddress);
+ remoteNodeConnected = true;
+ }
+
+ function disconnectRemoteNode() {
+ console.log("disconnecting remote node");
+ persistentSettings.useRemoteNode = false;
+ currentDaemonAddress = localDaemonAddress
+ currentWallet.initAsync(currentDaemonAddress);
+ remoteNodeConnected = false;
+ }
+
function onWalletRefresh() {
console.log(">>> wallet refreshed")
@@ -383,6 +411,31 @@ ApplicationWindow {
// Update transfer page status
middlePanel.updateStatus();
+ // Use remote node while local daemon is syncing
+ if (persistentSettings.useRemoteNode) {
+ var localNodeConnected = walletManager.connected;
+ var localNodeSynced = localNodeConnected && walletManager.localDaemonSynced()
+ if (!currentWallet.connected() || !localNodeSynced) {
+ console.log("Using remote node while local node is syncing")
+ // Connect to remote node if not already connected
+ if(!remoteNodeConnected) {
+ connectRemoteNode();
+ }
+
+ //update local daemon sync progress bar
+ if(localNodeConnected) {
+ leftPanel.progressBar.updateProgress(walletManager.blockchainHeight(),walletManager.blockchainTargetHeight(), 0, qsTr("Remaining blocks (local node):"));
+ leftPanel.progressBar.visible = true
+ } else if (persistentSettings.startLocalNode && !startLocalNodeCancelled) {
+ daemonManagerDialog.open()
+ }
+
+ // local daemon is synced - use it!
+ } else if (localNodeSynced && remoteNodeConnected) {
+ disconnectRemoteNode();
+ }
+ }
+
// Refresh is succesfull if blockchain height > 1
if (currentWallet.blockChainHeight() > 1){
@@ -392,9 +445,6 @@ ApplicationWindow {
console.log("Saving wallet after first refresh");
currentWallet.store()
isNewWallet = false
-
- // Update History
- currentWallet.history.refresh();
}
// recovering from seed is finished after first refresh
@@ -403,6 +453,10 @@ ApplicationWindow {
}
}
+ // Update history on every refresh if it's empty
+ if(currentWallet.history.count == 0)
+ currentWallet.history.refresh()
+
onWalletUpdate();
}
@@ -462,7 +516,8 @@ ApplicationWindow {
function onWalletMoneyReceived(txId, amount) {
// refresh transaction history here
currentWallet.refresh()
- currentWallet.history.refresh() // this will refresh model
+ console.log("Confirmed money found")
+ // history refresh is handled by walletUpdated
}
function onWalletUnconfirmedMoneyReceived(txId, amount) {
@@ -473,6 +528,7 @@ ApplicationWindow {
function onWalletMoneySent(txId, amount) {
// refresh transaction history here
+ console.log("money sent found")
currentWallet.refresh()
currentWallet.history.refresh() // this will refresh model
}
@@ -706,7 +762,7 @@ ApplicationWindow {
", txid: ", txid,
", txkey: ", txkey);
- var result = walletManager.checkPayment(address, txid, txkey, persistentSettings.daemon_address);
+ var result = walletManager.checkPayment(address, txid, txkey, currentDaemonAddress);
var results = result.split("|");
if (results.length < 4) {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
@@ -797,7 +853,7 @@ ApplicationWindow {
objectName: "appWindow"
visible: true
-// width: Screen.width //rightPanelExpanded ? 1269 : 1269 - 300
+// width: screenWidth //rightPanelExpanded ? 1269 : 1269 - 300
// height: 900 //300//maxWindowHeight;
color: "#FFFFFF"
flags: persistentSettings.customDecorations ? (Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint) : (Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint)
@@ -892,6 +948,9 @@ ApplicationWindow {
property string daemonPassword: ""
property bool transferShowAdvanced: false
property string blockchainDataDir: ""
+ property bool startLocalNode: true
+ property bool useRemoteNode: false
+ property string remoteNodeAddress: ""
}
// Information dialog
@@ -899,6 +958,8 @@ ApplicationWindow {
// dynamically change onclose handler
property var onCloseCallback
id: informationPopup
+ anchors.fill: parent
+ z: parent.z + 1
cancelVisible: false
onAccepted: {
if (onCloseCallback) {
@@ -909,6 +970,7 @@ ApplicationWindow {
// Confrirmation aka question dialog
StandardDialog {
+ z: parent.z + 1
id: transactionConfirmationPopup
onAccepted: {
close();
@@ -935,7 +997,9 @@ ApplicationWindow {
}
StandardDialog {
+ z: parent.z + 1
id: confirmationDialog
+ anchors.fill: parent
property var onAcceptedCallback
property var onRejectedCallback
onAccepted: {
@@ -955,9 +1019,17 @@ ApplicationWindow {
title: "Please choose a file"
folder: "file://" +moneroAccountsDir
nameFilters: [ "Wallet files (*.keys)"]
+ sidebarVisible: false
+
onAccepted: {
persistentSettings.wallet_path = walletManager.urlToLocalPath(fileDialog.fileUrl)
+ if(isIOS)
+ persistentSettings.wallet_path = persistentSettings.wallet_path.replace(moneroAccountsDir,"")
+ console.log("ÖPPPPNA")
+ console.log(moneroAccountsDir)
+ console.log(fileDialog.fileUrl)
+ console.log(persistentSettings.wallet_path)
initialize();
}
onRejected: {
@@ -967,9 +1039,63 @@ ApplicationWindow {
}
+ // Choose blockchain folder
+ FileDialog {
+ id: blockchainFileDialog
+ title: "Please choose a folder"
+ selectFolder: true
+ folder: "file://" + persistentSettings.blockchainDataDir
+
+ onAccepted: {
+ var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl)
+ var validator = daemonManager.validateDataDir(dataDir);
+ if(!validator.valid) {
+
+ confirmationDialog.title = qsTr("Warning") + translationManager.emptyString;
+ confirmationDialog.text = "";
+ if(validator.readOnly)
+ confirmationDialog.text += qsTr("Error: Filesystem is read only") + "\n\n"
+ if(validator.storageAvailable < 20)
+ confirmationDialog.text += qsTr("Warning: There's only %1 GB available on the device. Blockchain requires ~%30 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
+ else
+ confirmationDialog.text += qsTr("Note: There's %1 GB available on the device. Blockchain requires ~%30 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
+ if(!validator.lmdbExists)
+ confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
+
+
+ confirmationDialog.icon = StandardIcon.Question
+ confirmationDialog.cancelText = qsTr("Cancel")
+
+ // Continue
+ confirmationDialog.onAcceptedCallback = function() {
+ persistentSettings.blockchainDataDir = dataDir
+ }
+
+ // Cancel
+ confirmationDialog.onRejectedCallback = function() {
+ };
+
+ confirmationDialog.open()
+ } else {
+ persistentSettings.blockchainDataDir = dataDir
+ }
+
+ delete validator;
+
+
+ }
+ onRejected: {
+ console.log("data dir selection canceled")
+ }
+
+ }
+
+
PasswordDialog {
id: passwordDialog
-
+ visible: false
+ z: parent.z + 1
+ anchors.fill: parent
onAccepted: {
appWindow.initialize();
}
@@ -988,11 +1114,43 @@ 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
onRejected: {
loadPage("Settings");
+ startLocalNodeCancelled = true
}
}
@@ -1001,8 +1159,8 @@ ApplicationWindow {
id: splash
width: appWindow.width / 1.5
height: appWindow.height / 2
- x: (appWindow.width - width) / 2 + appWindow.x
- y: (appWindow.height - height) / 2 + appWindow.y
+ x: (appWindow.width - width) / 2
+ y: (appWindow.height - height) / 2
messageText: qsTr("Please wait...")
}
@@ -1020,14 +1178,15 @@ ApplicationWindow {
PropertyChanges { target: middlePanel; visible: false }
PropertyChanges { target: titleBar; basicButtonVisible: false }
PropertyChanges { target: wizard; visible: true }
- PropertyChanges { target: appWindow; width: (Screen.width < 930)? Screen.width : 930; }
+ PropertyChanges { target: appWindow; width: (screenWidth < 930 || isAndroid || isIOS)? screenWidth : 930; }
PropertyChanges { target: appWindow; height: maxWindowHeight; }
- PropertyChanges { target: resizeArea; visible: false }
+ PropertyChanges { target: resizeArea; visible: true }
PropertyChanges { target: titleBar; maximizeButtonVisible: false }
// PropertyChanges { target: frameArea; blocked: true }
PropertyChanges { target: titleBar; visible: false }
PropertyChanges { target: titleBar; y: 0 }
PropertyChanges { target: titleBar; title: qsTr("Program setup wizard") + translationManager.emptyString }
+ PropertyChanges { target: mobileHeader; visible: false }
}, State {
name: "normal"
PropertyChanges { target: leftPanel; visible: (isMobile)? false : true }
@@ -1035,7 +1194,7 @@ ApplicationWindow {
PropertyChanges { target: middlePanel; visible: true }
PropertyChanges { target: titleBar; basicButtonVisible: true }
PropertyChanges { target: wizard; visible: false }
- PropertyChanges { target: appWindow; width: (Screen.width < 969)? Screen.width : 969 } //rightPanelExpanded ? 1269 : 1269 - 300;
+ PropertyChanges { target: appWindow; width: (screenWidth < 969 || isAndroid || isIOS)? screenWidth : 969 } //rightPanelExpanded ? 1269 : 1269 - 300;
PropertyChanges { target: appWindow; height: maxWindowHeight; }
PropertyChanges { target: resizeArea; visible: true }
PropertyChanges { target: titleBar; maximizeButtonVisible: true }
@@ -1043,6 +1202,7 @@ ApplicationWindow {
PropertyChanges { target: titleBar; visible: true }
// PropertyChanges { target: titleBar; y: 0 }
PropertyChanges { target: titleBar; title: qsTr("Monero") + translationManager.emptyString }
+ PropertyChanges { target: mobileHeader; visible: isMobile ? true : false }
}
]
@@ -1051,7 +1211,7 @@ ApplicationWindow {
visible: isMobile
anchors.left: parent.left
anchors.right: parent.right
- height: visible? 65 : 0
+ height: visible? 65 * scaleRatio : 0
}
LeftPanel {
@@ -1068,6 +1228,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 {
@@ -1094,22 +1255,6 @@ ApplicationWindow {
visible: false
}
-// MouseArea {
-// id: frameArea
-// property bool blocked: false
-// anchors.top: parent.top
-// anchors.left: parent.left
-// anchors.right: parent.right
-// height: 30
-// z: 1
-// hoverEnabled: true
-// propagateComposedEvents: true
-// onPressed: mouse.accepted = false
-// onReleased: mouse.accepted = false
-// onMouseXChanged: titleBar.mouseX = mouseX
-// onContainsMouseChanged: titleBar.containsMouse = containsMouse
-// }
-
SequentialAnimation {
id: goToBasicAnimation
// PropertyAction {
@@ -1324,7 +1469,7 @@ ApplicationWindow {
y: 6
lineHeight: 0.7
font.family: "Arial"
- font.pixelSize: 12
+ font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
}
}
@@ -1335,11 +1480,70 @@ ApplicationWindow {
}
}
+ // TODO: Make the callback dynamic
+ Timer {
+ id: statusMessageTimer
+ interval: 5;
+ running: false;
+ repeat: false
+ onTriggered: resetAndroidClose()
+ triggeredOnStart: false
+ }
+
+ Rectangle {
+ id: statusMessage
+ z: 99
+ visible: false
+ property alias text: statusMessageText.text
+ anchors.bottom: parent.bottom
+ width: statusMessageText.contentWidth + 20 * scaleRatio
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "black"
+ height: 40 * scaleRatio
+ Text {
+ id: statusMessageText
+ anchors.fill: parent
+ anchors.margins: 10 * scaleRatio
+ font.pixelSize: 14 * scaleRatio
+ color: "white"
+ }
+ }
+
+ function resetAndroidClose() {
+ console.log("resetting android close");
+ androidCloseTapped = false;
+ statusMessage.visible = false
+ }
+
+ function showStatusMessage(msg,timeout) {
+ console.log("showing status message")
+ statusMessageTimer.interval = timeout * 1000;
+ statusMessageTimer.start()
+ statusMessageText.text = msg;
+ statusMessage.visible = true
+ }
+
onClosing: {
+ close.accepted = false;
+ console.log("blocking close event");
+ if(isAndroid) {
+ console.log("blocking android exit");
+ if(qrScannerEnabled)
+ cameraUi.state = "Stopped"
+
+ if(!androidCloseTapped) {
+ androidCloseTapped = true;
+ appWindow.showStatusMessage(qsTr("Tap again to close..."),3)
+
+ // first close
+ return;
+ }
+
+
+ }
// If daemon is running - prompt user before exiting
if(typeof daemonManager != "undefined" && daemonManager.running(persistentSettings.testnet)) {
- close.accepted = false;
// Show confirmation dialog
confirmationDialog.title = qsTr("Daemon is running") + translationManager.emptyString;
@@ -1363,6 +1567,7 @@ ApplicationWindow {
}
function closeAccepted(){
+ console.log("close accepted");
// Close wallet non async on exit
daemonManager.exit();
walletManager.closeWallet();
@@ -1407,4 +1612,14 @@ ApplicationWindow {
return false
}
+ function releaseFocus() {
+ // Workaround to release focus from textfield when scrolling (https://bugreports.qt.io/browse/QTBUG-34867)
+ if(isAndroid) {
+ console.log("releasing focus")
+ middlePanel.focus = true
+ middlePanel.focus = false
+ }
+
+
+ }
}
diff --git a/monero-wallet-gui.pro b/monero-wallet-gui.pro
index b6383d2b..3bb14914 100644
--- a/monero-wallet-gui.pro
+++ b/monero-wallet-gui.pro
@@ -86,7 +86,7 @@ ios:arm64 {
LIBS += \
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
}
-!ios {
+!ios:!android {
LIBS += -L$$WALLET_ROOT/lib \
-lwallet_merged \
-lepee \
@@ -95,6 +95,17 @@ LIBS += -L$$WALLET_ROOT/lib \
-lreadline \
}
+android {
+ message("Host is Android")
+ LIBS += -L$$WALLET_ROOT/lib \
+ -lwallet_merged \
+ -lepee \
+ -lunbound \
+ -leasylogging
+}
+
+
+
ios {
message("Host is IOS")
@@ -105,7 +116,8 @@ ios {
LIBS += -L$$WALLET_ROOT/lib-ios \
-lwallet_merged \
-lepee \
- -lunbound
+ -lunbound \
+ -leasylogging
LIBS+= \
-L$$PWD/../OpenSSL-for-iPhone/lib \
diff --git a/pages/AddressBook.qml b/pages/AddressBook.qml
index 65f097c0..7904c594 100644
--- a/pages/AddressBook.qml
+++ b/pages/AddressBook.qml
@@ -33,167 +33,106 @@ import moneroComponents.AddressBook 1.0
import moneroComponents.AddressBookModel 1.0
Rectangle {
- color: "#F0EEEE"
id: root
+ color: "#F0EEEE"
property var model
- Text {
- id: newEntryText
+ ColumnLayout {
+ anchors.margins: 17 * scaleRatio
anchors.left: parent.left
- anchors.right: parent.right
anchors.top: parent.top
- anchors.leftMargin: 17
- anchors.topMargin: 17
+ anchors.right: parent.right
+ spacing: 10 * scaleRatio
- elide: Text.ElideRight
- font.family: "Arial"
- font.pixelSize: 18
- color: "#4A4949"
- text: qsTr("Add new entry") + translationManager.emptyString
- }
-
- Label {
- id: addressLabel
- anchors.left: parent.left
- anchors.top: newEntryText.bottom
- anchors.leftMargin: 17
- anchors.topMargin: 17
- text: qsTr("Address") + translationManager.emptyString
- fontSize: 14
- }
-
- StandardButton {
- id: qrfinderButton
- anchors.left: parent.left
- anchors.leftMargin: 17
- anchors.topMargin: 5
- anchors.top: addressLabel.bottom
- text: qsTr("QRCODE") + translationManager.emptyString
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- visible : appWindow.qrScannerEnabled
- enabled : visible
- width: visible ? 60 : 0
- onClicked: {
- cameraUi.state = "Capture"
- cameraUi.qrcode_decoded.connect(updateFromQrCode)
+ Label {
+ id: addressLabel
+ anchors.left: parent.left
+ text: qsTr("Address") + translationManager.emptyString
}
- }
- LineEdit {
- id: addressLine
- anchors.left: qrfinderButton.right
- anchors.right: parent.right
- anchors.top: addressLabel.bottom
- anchors.rightMargin: 17
- anchors.topMargin: 5
- error: true;
- placeholderText: qsTr("4...") + translationManager.emptyString
- }
+ RowLayout {
+ StandardButton {
+ id: qrfinderButton
+ text: qsTr("Qr Code") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ visible : appWindow.qrScannerEnabled
+ enabled : visible
+ width: visible ? 60 * scaleRatio : 0
+ onClicked: {
+ cameraUi.state = "Capture"
+ cameraUi.qrcode_decoded.connect(updateFromQrCode)
+ }
+ }
- Label {
- id: paymentIdLabel
- anchors.left: parent.left
- anchors.top: addressLine.bottom
- anchors.leftMargin: 17
- anchors.topMargin: 17
- text: qsTr("Payment ID (Optional)") + translationManager.emptyString
- fontSize: 14
- }
+ LineEdit {
+ Layout.fillWidth: true;
+ id: addressLine
+ error: true;
+ placeholderText: qsTr("4...") + translationManager.emptyString
+ }
+ }
- LineEdit {
- id: paymentIdLine
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: paymentIdLabel.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 5
- placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString
- }
+ Label {
+ id: paymentIdLabel
+ text: qsTr("Payment ID (Optional)") + translationManager.emptyString
+ tipText: qsTr("Payment ID
A unique user name used in
the address book. It is not a
transfer of information sent
during the transfer")
+ + translationManager.emptyString
+ }
- Label {
- id: descriptionLabel
- anchors.left: parent.left
- anchors.top: paymentIdLine.bottom
- anchors.leftMargin: 17
- anchors.topMargin: 17
- text: qsTr("Description (Optional)") + translationManager.emptyString
- fontSize: 14
- }
+ LineEdit {
+ id: paymentIdLine
+ Layout.fillWidth: true;
+ placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString
+ }
- LineEdit {
- id: descriptionLine
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: descriptionLabel.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 5
- placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString
- }
+ Label {
+ id: descriptionLabel
+ text: qsTr("Description (Optional)") + translationManager.emptyString
+ }
+
+ LineEdit {
+ id: descriptionLine
+ Layout.fillWidth: true;
+ placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString
+ }
- RowLayout {
- id: addButton
- anchors.left: parent.left
- anchors.top: descriptionLine.bottom
- anchors.leftMargin: 17
- anchors.topMargin: 17
+ RowLayout {
+ id: addButton
+ Layout.bottomMargin: 17 * scaleRatio
+ StandardButton {
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ text: qsTr("Add") + translationManager.emptyString
+ enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
- StandardButton {
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- text: qsTr("Add") + translationManager.emptyString
- enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
+ onClicked: {
+ if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
+ informationPopup.title = qsTr("Error") + translationManager.emptyString;
+ // TODO: check currentWallet.addressBook.errorString() instead.
+ if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
+ informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
+ else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
+ informationPopup.text = currentWallet.addressBook.errorString()
+ else
+ informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
- onClicked: {
- if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
- informationPopup.title = qsTr("Error") + translationManager.emptyString;
- // TODO: check currentWallet.addressBook.errorString() instead.
- if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
- informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
- else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
- informationPopup.text = currentWallet.addressBook.errorString()
- else
- informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
-
- informationPopup.onCloseCallback = null
- informationPopup.open();
- } else {
- addressLine.text = "";
- paymentIdLine.text = "";
- descriptionLine.text = "";
+ informationPopup.onCloseCallback = null
+ informationPopup.open();
+ } else {
+ addressLine.text = "";
+ paymentIdLine.text = "";
+ descriptionLine.text = "";
+ }
}
}
}
- }
-
-
- Item {
- id: expandItem
- property bool expanded: false
-
- anchors.right: parent.right
- anchors.bottom: tableRect.top
- width: 34
- height: 34
-
- Image {
- anchors.centerIn: parent
- source: "../images/expandTable.png"
- rotation: parent.expanded ? 180 : 0
- }
-
- MouseArea {
- anchors.fill: parent
- onClicked: parent.expanded = !parent.expanded
- }
}
Rectangle {
@@ -201,8 +140,7 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
- height: expandItem.expanded ? parent.height - newEntryText.y - newEntryText.height - 17 :
- parent.height - addButton.y - addButton.height - 17
+ height: parent.height - addButton.y - addButton.height - 36 * scaleRatio
color: "#FFFFFF"
Behavior on height {
@@ -217,44 +155,6 @@ Rectangle {
color: "#DBDBDB"
}
- ListModel {
- id: columnsModel
-// ListElement { columnName: qsTr("Address") + translationManager.emptyString; columnWidth: 148 }
-// ListElement { columnName: qsTr("Payment ID") + translationManager.emptyString; columnWidth: 148 }
-// ListElement { columnName: qsTr("Description") + translationManager.emptyString; columnWidth: 148 }
-//
- }
-
- TableHeader {
- id: header
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.topMargin: 17
- anchors.leftMargin: 14
- anchors.rightMargin: 14
- dataModel: columnsModel
- onSortRequest: console.log("column: " + column + " desc: " + desc)
- }
-
- ListModel {
- id: testModel
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
- ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "" }
- }
-
Scroll {
id: flickableScroll
anchors.right: table.right
@@ -268,7 +168,7 @@ Rectangle {
id: table
anchors.left: parent.left
anchors.right: parent.right
- anchors.top: header.bottom
+ anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.leftMargin: 14
anchors.rightMargin: 14
diff --git a/pages/History.qml b/pages/History.qml
index cd8b03d8..9b184741 100644
--- a/pages/History.qml
+++ b/pages/History.qml
@@ -80,7 +80,7 @@ Rectangle {
}
onModelChanged: {
- if (typeof model !== 'undefined') {
+ if (typeof model !== 'undefined' && model != null) {
selectedAmount.text = getSelectedAmount()
@@ -146,30 +146,6 @@ Rectangle {
fontSize: 14
}
-
- // Filter by Address input (senseless, removing)
- /*
- Label {
- id: addressLabel
- anchors.left: parent.left
- anchors.top: filterHeaderText.bottom
- anchors.leftMargin: 17
- anchors.topMargin: 17
- text: qsTr("Address")
- fontSize: 14
- }
-
- LineEdit {
- id: addressLine
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: addressLabel.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 5
- }
- */
-
// Filter by string
LineEdit {
visible: !isMobile
@@ -488,7 +464,7 @@ Rectangle {
ListModel {
id: columnsModel
-
+ property int pidWidth: 127 * scaleRatio
ListElement { columnName: "Payment ID"; columnWidth: 127 }
ListElement { columnName: "Date"; columnWidth: 100 }
ListElement { columnName: "Block height"; columnWidth: 150 }
@@ -498,12 +474,13 @@ Rectangle {
TableHeader {
id: header
+ visible: !isMobile
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
- anchors.topMargin: 17
- anchors.leftMargin: 14
- anchors.rightMargin: 14
+ anchors.topMargin: 17 * scaleRatio
+ anchors.leftMargin: 14 * scaleRatio
+ anchors.rightMargin: 14 * scaleRatio
dataModel: columnsModel
offset: 20
onSortRequest: {
@@ -532,8 +509,9 @@ Rectangle {
Scroll {
id: flickableScroll
+ visible: !isMobile
anchors.right: table.right
- anchors.rightMargin: -14
+ anchors.rightMargin: !isMobile ? -14 * scaleRatio : 0
anchors.top: table.top
anchors.bottom: table.bottom
flickable: table
@@ -541,19 +519,37 @@ Rectangle {
HistoryTable {
id: table
+ visible: !isMobile
anchors.left: parent.left
anchors.right: parent.right
anchors.top: header.bottom
anchors.bottom: parent.bottom
- anchors.leftMargin: 14
- anchors.rightMargin: 14
+ anchors.leftMargin: 14 * scaleRatio
+ anchors.rightMargin: 14 * scaleRatio
onContentYChanged: flickableScroll.flickableContentYChanged()
- model: root.model
+ model: !isMobile ? root.model : null
+ addressBookModel: null
+ }
+
+ HistoryTableMobile {
+ id: tableMobile
+ visible: isMobile
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ onContentYChanged: flickableScroll.flickableContentYChanged()
+ model: isMobile ? root.model : null
addressBookModel: null
}
}
function onPageCompleted() {
- table.addressBookModel = appWindow.currentWallet ? appWindow.currentWallet.addressBookModel : null
+ if(currentWallet != null && typeof currentWallet.history !== "undefined" ) {
+ currentWallet.history.refresh()
+ table.addressBookModel = currentWallet ? currentWallet.addressBookModel : null
+ transactionTypeDropdown.update()
+ }
+
}
}
diff --git a/pages/Keys.qml b/pages/Keys.qml
new file mode 100644
index 00000000..3fad708d
--- /dev/null
+++ b/pages/Keys.qml
@@ -0,0 +1,221 @@
+// 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: {
+ appWindow.showStatusMessage(qsTr("Double tap to copy"),3)
+ }
+ onDoubleClicked: {
+ parent.selectAll()
+ parent.copy()
+ parent.deselect()
+ console.log("copied to clipboard");
+ appWindow.showStatusMessage(qsTr("Seed copied to clipboard"),3)
+ }
+ }
+ }
+ }
+
+ 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: {
+ appWindow.showStatusMessage(qsTr("Double tap to copy"),3)
+ }
+ onDoubleClicked: {
+ parent.selectAll()
+ parent.copy()
+ parent.deselect()
+ console.log("copied to clipboard");
+ appWindow.showStatusMessage(qsTr("Keys copied to clipboard"),3)
+ }
+ }
+ }
+ }
+
+ 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/Mining.qml b/pages/Mining.qml
index 2099a45e..0d87310f 100644
--- a/pages/Mining.qml
+++ b/pages/Mining.qml
@@ -37,6 +37,15 @@ Rectangle {
color: "#F0EEEE"
property var currentHashRate: 0
+ function isDaemonLocal() {
+ if (appWindow.currentDaemonAddress === "")
+ return false
+ var daemonHost = appWindow.currentDaemonAddress.split(":")[0]
+ if (daemonHost === "127.0.0.1" || daemonHost === "localhost")
+ return true
+ return false
+ }
+
/* main layout */
ColumnLayout {
id: mainLayout
diff --git a/pages/Receive.qml b/pages/Receive.qml
index 059b725b..b22ddfcd 100644
--- a/pages/Receive.qml
+++ b/pages/Receive.qml
@@ -169,24 +169,23 @@ Rectangle {
ColumnLayout {
id: mainLayout
anchors.margins: (isMobile)? 17 : 40
- anchors.topMargin: 40
+ anchors.topMargin: 40 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- spacing: 20
- property int labelWidth: 120
- property int editWidth: 400
- property int lineEditFontSize: 12
- property int qrCodeSize: 240
+ spacing: 20 * scaleRatio
+ property int labelWidth: 120 * scaleRatio
+ property int editWidth: 400 * scaleRatio
+ property int lineEditFontSize: 12 * scaleRatio
+ property int qrCodeSize: 240 * scaleRatio
ColumnLayout {
id: addressRow
Label {
id: addressLabel
- fontSize: 14
text: qsTr("Address") + translationManager.emptyString
width: mainLayout.labelWidth
}
@@ -206,6 +205,7 @@ Rectangle {
if (addressLine.text.length > 0) {
console.log(addressLine.text + " copied to clipboard")
clipboard.setText(addressLine.text)
+ appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3)
}
}
}
@@ -218,7 +218,6 @@ Rectangle {
Label {
Layout.columnSpan: 2
id: paymentIdLabel
- fontSize: 14
text: qsTr("Payment ID") + translationManager.emptyString
width: mainLayout.labelWidth
}
@@ -239,6 +238,7 @@ Rectangle {
onClicked: {
if (paymentIdLine.text.length > 0) {
clipboard.setText(paymentIdLine.text)
+ appWindow.showStatusMessage(qsTr("Payment ID copied to clipboard"),3)
}
}
}
@@ -246,7 +246,6 @@ Rectangle {
StandardButton {
id: generatePaymentId
- width: 80
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -258,7 +257,6 @@ Rectangle {
StandardButton {
id: clearPaymentId
enabled: !!paymentIdLine.text
- width: 80
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -272,7 +270,6 @@ Rectangle {
id: integratedAddressRow
Label {
id: integratedAddressLabel
- fontSize: 14
text: qsTr("Integrated address") + translationManager.emptyString
width: mainLayout.labelWidth
}
@@ -294,6 +291,7 @@ Rectangle {
onClicked: {
if (integratedAddressLine.text.length > 0) {
clipboard.setText(integratedAddressLine.text)
+ appWindow.showStatusMessage(qsTr("Integrated address copied to clipboard"),3)
}
}
}
@@ -305,7 +303,6 @@ Rectangle {
id: amountRow
Label {
id: amountLabel
- fontSize: 14
text: qsTr("Amount") + translationManager.emptyString
width: mainLayout.labelWidth
}
@@ -330,10 +327,9 @@ Rectangle {
RowLayout {
id: trackingRow
-
+ visible: !isAndroid && !isIOS
Label {
id: trackingLabel
- fontSize: 14
textFormat: Text.RichText
text: qsTr("\
Tracking (help)")
@@ -392,33 +388,33 @@ Rectangle {
}
}
}
-
- Menu {
- id: qrMenu
- title: "QrCode"
- MenuItem {
- text: qsTr("Save As") + translationManager.emptyString;
- onTriggered: qrFileDialog.open()
- }
- }
-
- Image {
- id: qrCode
- anchors.margins: 50
- anchors.top: trackingRow.bottom
- Layout.fillWidth: true
- Layout.minimumHeight: mainLayout.qrCodeSize
- smooth: false
- fillMode: Image.PreserveAspectFit
- source: "image://qrcode/" + makeQRCodeString()
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.RightButton
- onClicked: {
- if (mouse.button == Qt.RightButton)
- qrMenu.popup()
+ ColumnLayout {
+ Menu {
+ id: qrMenu
+ title: "QrCode"
+ MenuItem {
+ text: qsTr("Save As") + translationManager.emptyString;
+ onTriggered: qrFileDialog.open()
+ }
+ }
+
+ Image {
+ id: qrCode
+ anchors.margins: 50 * scaleRatio
+ Layout.fillWidth: true
+ Layout.minimumHeight: mainLayout.qrCodeSize
+ smooth: false
+ fillMode: Image.PreserveAspectFit
+ source: "image://qrcode/" + makeQRCodeString()
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ onClicked: {
+ if (mouse.button == Qt.RightButton)
+ qrMenu.popup()
+ }
+ onPressAndHold: qrFileDialog.open()
}
- onPressAndHold: qrFileDialog.open()
}
}
}
diff --git a/pages/Settings.qml b/pages/Settings.qml
index 61e1cd16..c020acab 100644
--- a/pages/Settings.qml
+++ b/pages/Settings.qml
@@ -38,7 +38,6 @@ import "../components"
import moneroComponents.Clipboard 1.0
Rectangle {
- property var daemonAddress
property bool viewOnly: false
id: page
@@ -48,20 +47,15 @@ Rectangle {
function initSettings() {
//runs on every page load
-
- // Daemon settings
- daemonAddress = persistentSettings.daemon_address.split(":");
- console.log("address: " + persistentSettings.daemon_address)
- // try connecting to daemon
}
ColumnLayout {
id: mainLayout
- anchors.margins: 17
+ anchors.margins: 17 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- spacing: 10
+ spacing: 10 * scaleRatio
//! Manage wallet
RowLayout {
@@ -70,8 +64,7 @@ Rectangle {
Layout.fillWidth: true
color: "#4A4949"
text: qsTr("Manage wallet") + translationManager.emptyString
- fontSize: 16
- Layout.topMargin: 10
+ Layout.topMargin: 10 * scaleRatio
}
}
@@ -82,7 +75,7 @@ Rectangle {
}
GridLayout {
- columns: (isMobile)? 2 : 4
+ columns: (isMobile)? 1 : 4
StandardButton {
id: closeWalletButton
text: qsTr("Close wallet") + translationManager.emptyString
@@ -111,18 +104,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 {
@@ -160,6 +141,7 @@ Rectangle {
*/
StandardButton {
id: rescanSpentButton
+ enabled: !persistentSettings.useRemoteNode
text: qsTr("Rescan wallet balance") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -184,16 +166,53 @@ Rectangle {
}
}
+ RowLayout {
+
+ StandardButton {
+ id: remoteDisconnect
+ enabled: persistentSettings.useRemoteNode
+ Layout.fillWidth: false
+ text: qsTr("Local Node") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ onClicked: {
+ appWindow.disconnectRemoteNode();
+ }
+ }
+
+ StandardButton {
+ id: remoteConnect
+ enabled: !persistentSettings.useRemoteNode
+ Layout.fillWidth: false
+ text: qsTr("Remote Node") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ onClicked: {
+ appWindow.connectRemoteNode();
+ }
+ }
+ }
+
//! Manage daemon
RowLayout {
+ visible: !isMobile
+ Layout.topMargin: 20
Label {
id: manageDaemonLabel
- Layout.fillWidth: true
color: "#4A4949"
- text: qsTr("Manage daemon") + translationManager.emptyString
- fontSize: 16
- anchors.topMargin: 30
- Layout.topMargin: 30
+ text: qsTr("Manage Daemon") + translationManager.emptyString
+ }
+
+ CheckBox {
+ id: daemonAdvanced
+ Layout.leftMargin: 15
+ text: qsTr("Show advanced") + translationManager.emptyString
+ checkedIcon: "../images/checkedVioletIcon.png"
+ uncheckedIcon: "../images/uncheckedIcon.png"
}
}
Rectangle {
@@ -203,27 +222,28 @@ Rectangle {
}
GridLayout {
+ visible: !isMobile
id: daemonStatusRow
columns: (isMobile) ? 2 : 4
StandardButton {
- visible: true
- enabled: !appWindow.daemonRunning
+ visible: !appWindow.daemonRunning
id: startDaemonButton
- text: qsTr("Start daemon") + translationManager.emptyString
+ text: qsTr("Start Local Node") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
+ // Set current daemon address to local
+ appWindow.currentDaemonAddress = appWindow.localDaemonAddress
appWindow.startDaemon(daemonFlags.text)
}
}
StandardButton {
- visible: true
- enabled: appWindow.daemonRunning
+ visible: appWindow.daemonRunning
id: stopDaemonButton
- text: qsTr("Stop daemon") + translationManager.emptyString
+ text: qsTr("Stop Local Node") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -246,16 +266,15 @@ Rectangle {
daemonConsolePopup.open();
}
}
-
}
- RowLayout {
+ ColumnLayout {
id: blockchainFolderRow
+ visible: !isMobile
Label {
id: blockchainFolderLabel
color: "#4A4949"
text: qsTr("Blockchain location") + translationManager.emptyString
- fontSize: 16
}
LineEdit {
id: blockchainFolder
@@ -278,13 +297,14 @@ Rectangle {
}
}
+
RowLayout {
+ visible: daemonAdvanced.checked && !isMobile
id: daemonFlagsRow
Label {
id: daemonFlagsLabel
color: "#4A4949"
- text: qsTr("Daemon startup flags") + translationManager.emptyString
- fontSize: 16
+ text: qsTr("Local daemon startup flags") + translationManager.emptyString
}
LineEdit {
id: daemonFlags
@@ -297,59 +317,21 @@ Rectangle {
RowLayout {
Layout.fillWidth: true
- spacing: 10
-
- Label {
- id: daemonAddrLabel
- Layout.fillWidth: true
- color: "#4A4949"
- text: qsTr("Daemon address") + translationManager.emptyString
- fontSize: 16
- }
- }
-
- GridLayout {
- id: daemonAddrRow
- Layout.fillWidth: true
- columnSpacing: 10
- columns: (isMobile) ? 2 : 3
-
- LineEdit {
- id: daemonAddr
- Layout.preferredWidth: 100
- Layout.fillWidth: true
- text: (daemonAddress !== undefined) ? daemonAddress[0] : ""
- placeholderText: qsTr("Hostname / IP") + translationManager.emptyString
- }
-
-
- LineEdit {
- id: daemonPort
- Layout.preferredWidth: 100
- Layout.fillWidth: true
- text: (daemonAddress !== undefined) ? daemonAddress[1] : "18081"
- placeholderText: qsTr("Port") + translationManager.emptyString
- }
- }
-
- RowLayout {
- Layout.fillWidth: true
- spacing: 10
+ visible: daemonAdvanced.checked || isMobile
Label {
id: daemonLoginLabel
Layout.fillWidth: true
color: "#4A4949"
- text: qsTr("Login (optional)") + translationManager.emptyString
- fontSize: 16
+ text: qsTr("Node login (optional)") + translationManager.emptyString
}
}
- RowLayout {
-
+ ColumnLayout {
+ visible: daemonAdvanced.checked || isMobile
LineEdit {
id: daemonUsername
- Layout.preferredWidth: 100
+ Layout.preferredWidth: 100 * scaleRatio
Layout.fillWidth: true
text: persistentSettings.daemonUsername
placeholderText: qsTr("Username") + translationManager.emptyString
@@ -358,50 +340,65 @@ Rectangle {
LineEdit {
id: daemonPassword
- Layout.preferredWidth: 100
+ Layout.preferredWidth: 100 * scaleRatio
Layout.fillWidth: true
text: persistentSettings.daemonPassword
placeholderText: qsTr("Password") + translationManager.emptyString
echoMode: TextInput.Password
}
+ }
- StandardButton {
- id: daemonAddrSave
- Layout.fillWidth: false
- Layout.leftMargin: 30
- text: qsTr("Connect") + translationManager.emptyString
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- onClicked: {
- console.log("saving daemon adress settings")
- var newDaemon = daemonAddr.text.trim() + ":" + daemonPort.text.trim()
- if(persistentSettings.daemon_address != newDaemon) {
- persistentSettings.daemon_address = newDaemon
+ RowLayout {
+ visible: persistentSettings.useRemoteNode
+ ColumnLayout {
+ Label {
+ color: "#4A4949"
+ text: qsTr("Remote node") + translationManager.emptyString
+ }
+ RemoteNodeEdit {
+ id: remoteNodeEdit
+ Layout.minimumWidth: 100 * scaleRatio
+ daemonAddrText: persistentSettings.remoteNodeAddress.split(":")[0].trim()
+ daemonPortText: (persistentSettings.remoteNodeAddress.split(":")[1].trim() == "") ? "18081" : persistentSettings.remoteNodeAddress.split(":")[1]
+ onEditingFinished: {
+ persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
+ console.log("setting remote node to " + persistentSettings.remoteNodeAddress)
}
+ }
- // Update daemon login
- persistentSettings.daemonUsername = daemonUsername.text;
- persistentSettings.daemonPassword = daemonPassword.text;
- currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
+ StandardButton {
+ id: remoteNodeSave
+ text: qsTr("Connect") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ onClicked: {
+ // Update daemon login
+ persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
+ persistentSettings.daemonUsername = daemonUsername.text;
+ persistentSettings.daemonPassword = daemonPassword.text;
+ persistentSettings.useRemoteNode = true
- //Reinit wallet
- currentWallet.initAsync(newDaemon);
+ currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
+
+ appWindow.connectRemoteNode()
+ }
}
}
}
RowLayout {
+ visible: !isMobile
Label {
color: "#4A4949"
text: qsTr("Layout settings") + translationManager.emptyString
- fontSize: 16
- anchors.topMargin: 30
- Layout.topMargin: 30
+ anchors.topMargin: 30 * scaleRatio
+ Layout.topMargin: 30 * scaleRatio
}
}
Rectangle {
+ visible: !isMobile
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
@@ -409,6 +406,7 @@ Rectangle {
RowLayout {
CheckBox {
+ visible: !isMobile
id: customDecorationsCheckBox
checked: persistentSettings.customDecorations
onClicked: appWindow.setCustomWindowDecorations(checked)
@@ -424,9 +422,8 @@ Rectangle {
Label {
color: "#4A4949"
text: qsTr("Log level") + translationManager.emptyString
- fontSize: 16
- anchors.topMargin: 30
- Layout.topMargin: 30
+ anchors.topMargin: 30 * scaleRatio
+ Layout.topMargin: 30 * scaleRatio
}
}
Rectangle {
@@ -454,7 +451,6 @@ Rectangle {
LineEdit {
id: logCategories
- Layout.preferredWidth: 200
Layout.fillWidth: true
text: appWindow.persistentSettings.logCategories
placeholderText: qsTr("(e.g. *:WARNING,net.p2p:DEBUG)") + translationManager.emptyString
@@ -475,8 +471,8 @@ Rectangle {
color: "#4A4949"
text: qsTr("Debug info") + translationManager.emptyString
fontSize: 16
- anchors.topMargin: 30
- Layout.topMargin: 30
+ anchors.topMargin: 30 * scaleRatio
+ Layout.topMargin: 30 * scaleRatio
}
}
Rectangle {
@@ -484,13 +480,11 @@ Rectangle {
height: 1
color: "#DEDEDE"
}
-
TextBlock {
Layout.topMargin: 8
Layout.fillWidth: true
text: qsTr("GUI version: ") + Version.GUI_VERSION + translationManager.emptyString
}
-
TextBlock {
id: guiMoneroVersion
Layout.fillWidth: true
@@ -588,61 +582,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
@@ -670,7 +609,6 @@ Rectangle {
if(!validator.lmdbExists) {
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
}
-
confirmationDialog.icon = StandardIcon.Question
confirmationDialog.cancelText = qsTr("Cancel")
@@ -703,7 +641,7 @@ Rectangle {
function onPageCompleted() {
console.log("Settings page loaded");
initSettings();
- viewOnly = currentWallet.viewOnly;
+
if(typeof daemonManager != "undefined")
appWindow.daemonRunning = daemonManager.running(persistentSettings.testnet)
@@ -713,8 +651,6 @@ Rectangle {
Component.onCompleted: {
if(typeof daemonManager != "undefined")
daemonManager.daemonConsoleUpdated.connect(onDaemonConsoleUpdated)
-
-
}
function onDaemonConsoleUpdated(message){
diff --git a/pages/Sign.qml b/pages/Sign.qml
index b8900e7f..3c57fac7 100644
--- a/pages/Sign.qml
+++ b/pages/Sign.qml
@@ -39,10 +39,6 @@ import moneroComponents.WalletManager 1.0
Rectangle {
id: mainLayout
- property int labelWidth: 120
-// property int editWidth: 400
- property int lineEditFontSize: 12
-
color: "#F0EEEE"
Clipboard { id: clipboard }
@@ -92,35 +88,31 @@ Rectangle {
// sign / verify
ColumnLayout {
- anchors.margins: 17
+ anchors.margins: 17 * scaleRatio
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
- spacing: 20
+ spacing: 20 * scaleRatio
// sign
ColumnLayout {
id: signBox
RowLayout {
- ColumnLayout {
- spacing: 8
- Label {
- text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString
- fontSize: 16
- wrapMode: Text.Wrap
- }
- Label {}
+
+ Text {
+ text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString
+ wrapMode: Text.Wrap
+ font.pixelSize: 14 * scaleRatio
+ Layout.fillWidth: true
}
}
Label {
id: signMessageLabel
- fontSize: 14
text: qsTr("Either message:") + translationManager.emptyString
- width: mainLayout.labelWidth
}
RowLayout {
@@ -133,10 +125,8 @@ Rectangle {
id: signMessageLine
anchors.left: parent.left
anchors.right: signMessageButton.left
- fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Message to sign") + translationManager.emptyString;
readOnly: false
-// Layout.fillWidth: true
onTextChanged: signSignatureLine.text = ""
IconButton {
@@ -152,7 +142,6 @@ Rectangle {
StandardButton {
id: signMessageButton
anchors.right: parent.right
- width: 60
text: qsTr("Sign") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -168,9 +157,7 @@ Rectangle {
Label {
id: signMessageFileLabel
- fontSize: 14
text: qsTr("Or file:") + translationManager.emptyString
- width: mainLayout.labelWidth
}
RowLayout {
@@ -192,8 +179,7 @@ Rectangle {
StandardButton {
id: loadFileToSignButton
- anchors.rightMargin: 17
- width: 60
+ anchors.rightMargin: 17 * scaleRatio
text: qsTr("Select") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -208,7 +194,6 @@ Rectangle {
id: signFileLine
anchors.left: loadFileToSignButton.right
anchors.right: signFileButton.left
- fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Filename with message to sign") + translationManager.emptyString;
readOnly: false
Layout.fillWidth: true
@@ -227,7 +212,6 @@ Rectangle {
StandardButton {
id: signFileButton
anchors.right: parent.right
- width: 60
text: qsTr("Sign") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -241,19 +225,17 @@ Rectangle {
}
}
- RowLayout {
+ ColumnLayout {
id: signSignatureRow
- anchors.topMargin: 17
+ anchors.topMargin: 17 * scaleRatio
Label {
id: signSignatureLabel
- fontSize: 14
text: qsTr("Signature") + translationManager.emptyString
}
LineEdit {
id: signSignatureLine
- fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Signature") + translationManager.emptyString;
readOnly: true
Layout.fillWidth: true
@@ -275,29 +257,24 @@ Rectangle {
ColumnLayout {
id: verifyBox
- RowLayout {
- ColumnLayout {
- spacing: 8
- Label {
- text: qsTr("Verify a message or file signature from an address:") + translationManager.emptyString
- fontSize: 16
-// Layout.fillWidth: true
- wrapMode: Text.Wrap
- }
- Label {}
+ RowLayout {
+ Text {
+ text: qsTr("Verify a message or file signature from an address:") + translationManager.emptyString
+ wrapMode: Text.Wrap
+ font.pixelSize: 14 * scaleRatio
+ Layout.fillWidth: true
}
+
}
Label {
id: verifyMessageLabel
- fontSize: 14
text: qsTr("Either message:") + translationManager.emptyString
- width: mainLayout.labelWidth
}
RowLayout {
id: verifyMessageRow
- anchors.topMargin: 17
+ anchors.topMargin: 17 * scaleRatio
anchors.left: parent.left
anchors.right: parent.right
@@ -305,7 +282,6 @@ Rectangle {
id: verifyMessageLine
anchors.left: parent.left
anchors.right: verifyMessageButton.left
- fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Message to verify") + translationManager.emptyString;
readOnly: false
Layout.fillWidth: true
@@ -323,7 +299,6 @@ Rectangle {
StandardButton {
id: verifyMessageButton
anchors.right: parent.right
- width: 60
text: qsTr("Verify") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -339,16 +314,14 @@ Rectangle {
Label {
id: verifyMessageFileLabel
- fontSize: 14
text: qsTr("Or file:") + translationManager.emptyString
- width: mainLayout.labelWidth
}
RowLayout {
id: verifyFileRow
- anchors.topMargin: 17
+ anchors.topMargin: 17 * scaleRatio
anchors.left: parent.left
- anchors.right: parent.right
+ anchors.right: parent.right
FileDialog {
id: verifyFileDialog
@@ -363,8 +336,7 @@ Rectangle {
StandardButton {
id: loadFileToVerifyButton
- anchors.rightMargin: 17
- width: 60
+ anchors.rightMargin: 17 * scaleRatio
text: qsTr("Select") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -379,7 +351,6 @@ Rectangle {
id: verifyFileLine
anchors.left: loadFileToVerifyButton.right
anchors.right: verifyFileButton.left
- fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Filename with message to verify") + translationManager.emptyString;
readOnly: false
Layout.fillWidth: true
@@ -397,7 +368,6 @@ Rectangle {
StandardButton {
id: verifyFileButton
anchors.right: parent.right
- width: 60
text: qsTr("Verify") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -411,18 +381,16 @@ Rectangle {
}
}
- Label {
+ Text {
id: verifyAddressLabel
- fontSize: 14
- width: mainLayout.labelWidth
- textFormat: Text.RichText
- text: qsTr("\
- Signing address ( Paste in or select from Address book )")
+ text: qsTr("\
+ Signing address ( Paste in or select from Address book )").arg(14 * scaleRatio).arg(2 * scaleRatio).arg(2 * scaleRatio)
+ translationManager.emptyString
-// Layout.fillWidth: true
wrapMode: Text.Wrap
-
- onLinkActivated: appWindow.showPageRequest("AddressBook")
+ font.pixelSize: 14 * scaleRatio
+ Layout.fillWidth: true
+ textFormat: Text.RichText
+ onLinkActivated: appWindow.showPageRequest("AddressBook")
}
LineEdit {
@@ -430,24 +398,22 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: verifyAddressLabel.bottom
- anchors.topMargin: 5
+ anchors.topMargin: 5 * scaleRatio
placeholderText: "4..."
// validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
}
- RowLayout {
+ ColumnLayout {
id: verifySignatureRow
- anchors.topMargin: 17
+ anchors.topMargin: 17 * scaleRatio
Label {
id: verifySignatureLabel
- fontSize: 14
text: qsTr("Signature") + translationManager.emptyString
}
LineEdit {
id: verifySignatureLine
- fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Signature") + translationManager.emptyString;
Layout.fillWidth: true
diff --git a/pages/Transfer.qml b/pages/Transfer.qml
index 13f20bce..29ca46ed 100644
--- a/pages/Transfer.qml
+++ b/pages/Transfer.qml
@@ -71,10 +71,10 @@ Rectangle {
}
function updateMixin() {
- var fillLevel = privacyLevelItem.fillLevel
+ var fillLevel = (isMobile) ? privacyLevelItemSmall.fillLevel : privacyLevelItem.fillLevel
var mixin = scaleValueToMixinCount(fillLevel)
- print ("PrivacyLevel changed:" + fillLevel)
- print ("mixin count: " + mixin)
+ console.log("PrivacyLevel changed:" + fillLevel)
+ console.log("mixin count: " + mixin)
privacyLabel.text = qsTr("Privacy level (ringsize %1)").arg(mixin+1) + translationManager.emptyString
}
@@ -107,297 +107,226 @@ Rectangle {
}
}
- Item {
+ ColumnLayout {
id: pageRoot
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
- anchors.topMargin: 20
- height: 400
+ anchors.margins: 17 * scaleRatio
+ spacing: 0
- Label {
- id: amountLabel
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 17
- text: qsTr("Amount") + translationManager.emptyString
- fontSize: 14
- }
+ GridLayout {
+ columns: (isMobile)? 1 : 2
+ Layout.fillWidth: true
- Label {
- id: transactionPriority
- anchors.top: parent.top
- anchors.topMargin: 17
- fontSize: 14
- x: (parent.width - 17) / 2 + 17
- text: qsTr("Transaction priority") + translationManager.emptyString
- }
+ ColumnLayout {
+ Layout.fillWidth: true
+ Label {
+ id: amountLabel
+ text: qsTr("Amount") + translationManager.emptyString
+ }
+
+ RowLayout {
+ Layout.fillWidth: true
+ id: amountRow
+ Layout.minimumWidth: 200
+ Item {
+ visible: !isMobile
+ width: 37 * scaleRatio
+ height: 37 * scaleRatio
+
+ Image {
+ anchors.centerIn: parent
+ source: "../images/moneroIcon.png"
+ }
+ }
+ // Amount input
+ LineEdit {
+ Layout.fillWidth: true
+ id: amountLine
+ placeholderText: qsTr("") + translationManager.emptyString
+ width:100
+ validator: DoubleValidator {
+ bottom: 0.0
+ top: 18446744.073709551615
+ decimals: 12
+ notation: DoubleValidator.StandardNotation
+ locale: "C"
+ }
+ }
+
+ StandardButton {
+ id: amountAllButton
+ width: 60 * scaleRatio
+ text: qsTr("All") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ enabled : true
+ onClicked: amountLine.text = "(all)"
+ }
+ }
- Row {
- id: amountRow
- anchors.top: amountLabel.bottom
- anchors.topMargin: 5
- anchors.left: parent.left
- anchors.leftMargin: 7
- width: (parent.width - 17) / 2 + 10
- Item {
- width: 37
- height: 37
+ }
- Image {
- anchors.centerIn: parent
- source: "../images/moneroIcon.png"
+ ColumnLayout {
+ Layout.fillWidth: true
+ Label {
+ id: transactionPriority
+ text: qsTr("Transaction priority") + translationManager.emptyString
+ }
+ // Note: workaround for translations in listElements
+ // ListElement: cannot use script for property value, so
+ // code like this wont work:
+ // ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low }
+ // For translations to work, the strings need to be listed in
+ // the file components/StandardDropdown.qml too.
+
+ // Priorities before v5
+ ListModel {
+ id: priorityModel
+
+ ListElement { column1: qsTr("Low (x1 fee)") ; column2: ""; priority: PendingTransaction.Priority_Low }
+ ListElement { column1: qsTr("Medium (x20 fee)") ; column2: ""; priority: PendingTransaction.Priority_Medium }
+ ListElement { column1: qsTr("High (x166 fee)") ; column2: ""; priority: PendingTransaction.Priority_High }
+ }
+
+ // Priorites after v5
+ ListModel {
+ id: priorityModelV5
+
+ ListElement { column1: qsTr("Slow (x0.25 fee)") ; column2: ""; priority: 1}
+ ListElement { column1: qsTr("Default (x1 fee)") ; column2: ""; priority: 2 }
+ ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 }
+ ListElement { column1: qsTr("Fastest (x41.5 fee)") ; column2: ""; priority: 4 }
+
+ }
+
+ StandardDropdown {
+ Layout.fillWidth: true
+ id: priorityDropdown
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
}
}
- // Amount input
- LineEdit {
- id: amountLine
- placeholderText: qsTr("") + translationManager.emptyString
- width: parent.width - 37 - 17 - 60
- validator: DoubleValidator {
- bottom: 0.0
- top: 18446744.073709551615
- decimals: 12
- notation: DoubleValidator.StandardNotation
- locale: "C"
+ // Make sure dropdown is on top
+ z: parent.z + 1
+ }
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ Label {
+ id: addressLabel
+ textFormat: Text.RichText
+ text: qsTr("\
+ Address ( Paste in or select from Address book )")
+ + translationManager.emptyString
+
+ onLinkActivated: appWindow.showPageRequest("AddressBook")
+ Layout.fillWidth: true
+ }
+ // recipient address input
+ RowLayout {
+ id: addressLineRow
+ Layout.fillWidth: true
+
+ StandardButton {
+ id: qrfinderButton
+ text: qsTr("QR Code") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ visible : appWindow.qrScannerEnabled
+ enabled : visible
+ width: visible ? 60 * scaleRatio : 0
+ onClicked: {
+ cameraUi.state = "Capture"
+ cameraUi.qrcode_decoded.connect(updateFromQrCode)
+ }
}
- }
-
- StandardButton {
- id: amountAllButton
- //anchors.left: amountLine.right
- //anchors.top: amountLine.top
- //anchors.bottom: amountLine.bottom
- width: 60
- text: qsTr("All") + translationManager.emptyString
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- enabled : true
- onClicked: amountLine.text = "(all)"
- }
- }
-
-
- // Note: workaround for translations in listElements
- // ListElement: cannot use script for property value, so
- // code like this wont work:
- // ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low }
- // For translations to work, the strings need to be listed in
- // the file components/StandardDropdown.qml too.
-
- // Priorities before v5
- ListModel {
- id: priorityModel
-
- ListElement { column1: qsTr("Low (x1 fee)") ; column2: ""; priority: PendingTransaction.Priority_Low }
- ListElement { column1: qsTr("Medium (x20 fee)") ; column2: ""; priority: PendingTransaction.Priority_Medium }
- ListElement { column1: qsTr("High (x166 fee)") ; column2: ""; priority: PendingTransaction.Priority_High }
- }
-
- // Priorites after v5
- ListModel {
- id: priorityModelV5
-
- ListElement { column1: qsTr("Slow (x0.25 fee)") ; column2: ""; priority: 1}
- ListElement { column1: qsTr("Default (x1 fee)") ; column2: ""; priority: 2 }
- ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 }
- ListElement { column1: qsTr("Fastest (x41.5 fee)") ; column2: ""; priority: 4 }
-
- }
-
- StandardDropdown {
- id: priorityDropdown
- anchors.top: transactionPriority.bottom
- anchors.right: parent.right
- anchors.rightMargin: 17
- anchors.topMargin: 5
- anchors.left: transactionPriority.left
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- z: 1
- }
-
- Label {
- id: addressLabel
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: amountRow.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 30
- fontSize: 14
- textFormat: Text.RichText
- text: qsTr("\
- Address ( Paste in or select from Address book )")
- + translationManager.emptyString
-
- onLinkActivated: appWindow.showPageRequest("AddressBook")
- }
- // recipient address input
- RowLayout {
- id: addressLineRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: addressLabel.bottom
-
- StandardButton {
- id: qrfinderButton
- anchors.left: parent.left
- anchors.leftMargin: 17
- anchors.topMargin: 5
- text: qsTr("QR Code") + translationManager.emptyString
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- visible : appWindow.qrScannerEnabled
- enabled : visible
- width: visible ? 60 : 0
- onClicked: {
- cameraUi.state = "Capture"
- cameraUi.qrcode_decoded.connect(updateFromQrCode)
+ LineEdit {
+ id: addressLine
+ Layout.fillWidth: true
+ anchors.topMargin: 5 * scaleRatio
+ placeholderText: "4..."
+ // validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
}
- }
- LineEdit {
- id: addressLine
- anchors.left: qrfinderButton.right
- anchors.right: resolveButton.left
- //anchors.leftMargin: 17
- anchors.topMargin: 5
- placeholderText: "4..."
- // validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
- }
- StandardButton {
- id: resolveButton
- anchors.right: parent.right
- anchors.leftMargin: 17
- anchors.topMargin: 17
- anchors.rightMargin: 17
- width: 60
- text: qsTr("Resolve") + translationManager.emptyString
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- enabled : isValidOpenAliasAddress(addressLine.text)
- onClicked: {
- var result = walletManager.resolveOpenAlias(addressLine.text)
- if (result) {
- var parts = result.split("|")
- if (parts.length == 2) {
- var address_ok = walletManager.addressValid(parts[1], appWindow.persistentSettings.testnet)
- if (parts[0] === "true") {
- if (address_ok) {
- addressLine.text = parts[1]
- addressLine.cursorPosition = 0
- }
- else
- oa_message(qsTr("No valid address found at this OpenAlias address"))
- } else if (parts[0] === "false") {
- if (address_ok) {
- addressLine.text = parts[1]
- addressLine.cursorPosition = 0
- oa_message(qsTr("Address found, but the DNSSEC signatures could not be verified, so this address may be spoofed"))
+ StandardButton {
+ id: resolveButton
+ width: 60 * scaleRatio
+ text: qsTr("Resolve") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ enabled : isValidOpenAliasAddress(addressLine.text)
+ onClicked: {
+ var result = walletManager.resolveOpenAlias(addressLine.text)
+ if (result) {
+ var parts = result.split("|")
+ if (parts.length == 2) {
+ var address_ok = walletManager.addressValid(parts[1], appWindow.persistentSettings.testnet)
+ if (parts[0] === "true") {
+ if (address_ok) {
+ addressLine.text = parts[1]
+ addressLine.cursorPosition = 0
+ }
+ else
+ oa_message(qsTr("No valid address found at this OpenAlias address"))
+ } else if (parts[0] === "false") {
+ if (address_ok) {
+ addressLine.text = parts[1]
+ addressLine.cursorPosition = 0
+ oa_message(qsTr("Address found, but the DNSSEC signatures could not be verified, so this address may be spoofed"))
+ } else {
+ oa_message(qsTr("No valid address found at this OpenAlias address, but the DNSSEC signatures could not be verified, so this may be spoofed"))
+ }
+ } else {
+ oa_message(qsTr("Internal error"))
+ }
} else {
- oa_message(qsTr("No valid address found at this OpenAlias address, but the DNSSEC signatures could not be verified, so this may be spoofed"))
+ oa_message(qsTr("Internal error"))
}
} else {
- oa_message(qsTr("Internal error"))
+ oa_message(qsTr("No address found"))
}
- } else {
- oa_message(qsTr("Internal error"))
- }
- } else {
- oa_message(qsTr("No address found"))
}
}
}
- }
- Label {
- id: paymentIdLabel
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: addressLineRow.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 17
- fontSize: 14
- text: qsTr("Payment ID ( Optional )") + translationManager.emptyString
- }
+ Label {
+ id: paymentIdLabel
+ text: qsTr("Payment ID ( Optional )") + translationManager.emptyString
+ }
- // payment id input
- LineEdit {
- id: paymentIdLine
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: paymentIdLabel.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 5
- placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
- // validator: DoubleValidator { top: 0.0 }
- }
+ // payment id input
+ LineEdit {
+ id: paymentIdLine
+ placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
+ Layout.fillWidth: true
+ }
- Label {
- id: descriptionLabel
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: paymentIdLine.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 17
- fontSize: 14
- text: qsTr("Description ( Optional )")
- + translationManager.emptyString
- }
+ Label {
+ text: qsTr("Description ( Optional )")
+ + translationManager.emptyString
+ }
- LineEdit {
- id: descriptionLine
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: descriptionLabel.bottom
- anchors.leftMargin: 17
- anchors.rightMargin: 17
- anchors.topMargin: 5
- placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString
- }
-
- function checkInformation(amount, address, payment_id, testnet) {
- address = address.trim()
- payment_id = payment_id.trim()
-
- var amount_ok = amount.length > 0
- var address_ok = walletManager.addressValid(address, testnet)
- var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
- var ipid = walletManager.paymentIdFromAddress(address, testnet)
- if (ipid.length > 0 && payment_id.length > 0)
- payment_id_ok = false
-
- addressLine.error = !address_ok
- amountLine.error = !amount_ok
- paymentIdLine.error = !payment_id_ok
-
- return amount_ok && address_ok && payment_id_ok
- }
-
-
- RowLayout {
- anchors.left: parent.left
- anchors.top: descriptionLine.bottom
- anchors.leftMargin: 17
- anchors.topMargin: 17
+ LineEdit {
+ id: descriptionLine
+ placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString
+ Layout.fillWidth: true
+ }
StandardButton {
id: sendButton
+ Layout.bottomMargin: 17 * scaleRatio
+ Layout.topMargin: 17 * scaleRatio
text: qsTr("Send") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -418,6 +347,23 @@ Rectangle {
}
}
+ function checkInformation(amount, address, payment_id, testnet) {
+ address = address.trim()
+ payment_id = payment_id.trim()
+
+ var amount_ok = amount.length > 0
+ var address_ok = walletManager.addressValid(address, testnet)
+ var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
+ var ipid = walletManager.paymentIdFromAddress(address, testnet)
+ if (ipid.length > 0 && payment_id.length > 0)
+ payment_id_ok = false
+
+ addressLine.error = !address_ok
+ amountLine.error = !amount_ok
+ paymentIdLine.error = !payment_id_ok
+
+ return amount_ok && address_ok && payment_id_ok
+ }
} // pageRoot
@@ -433,8 +379,10 @@ Rectangle {
anchors.top: pageRoot.bottom
anchors.left: parent.left
anchors.right: parent.right
- anchors.margins: 17
- spacing:10
+ anchors.leftMargin: 17 * scaleRatio
+ anchors.topMargin: 17 * scaleRatio
+ anchors.bottomMargin: 17 * scaleRatio
+ spacing: 10 * scaleRatio
enabled: !viewOnly || pageRoot.enabled
RowLayout {
@@ -455,13 +403,14 @@ Rectangle {
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
- Layout.bottomMargin: 30
+ Layout.bottomMargin: 30 * scaleRatio
}
RowLayout {
visible: persistentSettings.transferShowAdvanced
anchors.left: parent.left
anchors.right: parent.right
+ Layout.fillWidth: true
Label {
id: privacyLabel
fontSize: 14
@@ -479,17 +428,27 @@ Rectangle {
PrivacyLevel {
- visible: persistentSettings.transferShowAdvanced
+ visible: persistentSettings.transferShowAdvanced && !isMobile
id: privacyLevelItem
anchors.left: parent.left
anchors.right: parent.right
+ anchors.rightMargin: 17 * scaleRatio
+ onFillLevelChanged: updateMixin()
+ }
+
+ PrivacyLevelSmall {
+ visible: persistentSettings.transferShowAdvanced && isMobile
+ id: privacyLevelItemSmall
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.rightMargin: 17 * scaleRatio
onFillLevelChanged: updateMixin()
}
GridLayout {
visible: persistentSettings.transferShowAdvanced
- Layout.topMargin: 50
+ Layout.topMargin: 50 * scaleRatio
columns: (isMobile) ? 2 : 6
@@ -657,8 +616,8 @@ Rectangle {
Rectangle {
x: root.width/2 - width/2
y: root.height/2 - height/2
- height:statusText.paintedHeight + 50
- width:statusText.paintedWidth + 40
+ height:statusText.paintedHeight + 50 * scaleRatio
+ width:statusText.paintedWidth + 40 * scaleRatio
visible: statusText.text != ""
opacity: 0.9
@@ -719,6 +678,7 @@ Rectangle {
statusText.text = qsTr("Waiting on daemon synchronization to finish")
} else {
// everything OK, enable transfer page
+ // Light wallet is always ready
pageRoot.enabled = true;
statusText.text = "";
}
diff --git a/qml.qrc b/qml.qrc
index 06f721c4..7f1b3c37 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -72,6 +72,7 @@
images/expandTable.png
images/dropdownDel.png
components/HistoryTable.qml
+ components/HistoryTableMobile.qml
images/gotoBasicVersion.png
images/goToBasicVersionHovered.png
BasicPanel.qml
@@ -143,5 +144,9 @@
components/Notifier.qml
components/MobileHeader.qml
components/TextBlock.qml
+ wizard/WizardDaemonSettings.qml
+ components/RemoteNodeEdit.qml
+ pages/Keys.qml
+ images/menu.png
diff --git a/src/QR-Code-scanner/QrCodeScanner.cpp b/src/QR-Code-scanner/QrCodeScanner.cpp
index 1129e986..62c639f9 100644
--- a/src/QR-Code-scanner/QrCodeScanner.cpp
+++ b/src/QR-Code-scanner/QrCodeScanner.cpp
@@ -61,15 +61,23 @@ void QrCodeScanner::processCode(int type, const QString &data)
emit notifyError(error);
return;
}
+ QVariantMap parsed_unknown_parameters;
if(unknown_parameters.size() > 0)
{
qDebug() << "unknown parameters " << unknown_parameters;
+ foreach(const QString &item, unknown_parameters )
+ {
+ QStringList parsed_item = item.split("=");
+ if(parsed_item.size() == 2) {
+ parsed_unknown_parameters.insert(parsed_item[0], parsed_item[1]);
+ }
+ }
emit notifyError(error, true);
}
qDebug() << "Parsed URI : " << address << " " << payment_id << " " << amount << " " << tx_description << " " << recipient_name << " " << error;
QString s_amount = WalletManager::instance()->displayAmount(amount);
qDebug() << "Amount passed " << s_amount ;
- emit decoded(address, payment_id, s_amount, tx_description, recipient_name);
+ emit decoded(address, payment_id, s_amount, tx_description, recipient_name, parsed_unknown_parameters);
}
void QrCodeScanner::processFrame(QVideoFrame frame)
{
@@ -102,3 +110,15 @@ void QrCodeScanner::timerEvent(QTimerEvent *event)
}
}
+QrCodeScanner::~QrCodeScanner()
+{
+ m_thread->stop();
+ m_thread->quit();
+ if(!m_thread->wait(5000))
+ {
+ m_thread->terminate();
+ m_thread->wait();
+ }
+
+}
+
diff --git a/src/QR-Code-scanner/QrCodeScanner.h b/src/QR-Code-scanner/QrCodeScanner.h
index a6a747b3..a83cf2ac 100644
--- a/src/QR-Code-scanner/QrCodeScanner.h
+++ b/src/QR-Code-scanner/QrCodeScanner.h
@@ -44,7 +44,7 @@ class QrCodeScanner : public QObject
public:
QrCodeScanner(QObject *parent = Q_NULLPTR);
-
+ ~QrCodeScanner();
void setSource(QCamera*);
bool enabled() const;
@@ -57,7 +57,7 @@ public Q_SLOTS:
Q_SIGNALS:
void enabledChanged();
- void decoded(const QString &address, const QString &payment_id, const QString &amount, const QString &tx_description, const QString &recipient_name);
+ void decoded(const QString &address, const QString &payment_id, const QString &amount, const QString &tx_description, const QString &recipient_name, const QVariantMap &extra_parameters);
void decode(int type, const QString &data);
void notifyError(const QString &error, bool warning = false);
diff --git a/src/QR-Code-scanner/QrScanThread.cpp b/src/QR-Code-scanner/QrScanThread.cpp
index b6e9b9ff..48ecb53a 100644
--- a/src/QR-Code-scanner/QrScanThread.cpp
+++ b/src/QR-Code-scanner/QrScanThread.cpp
@@ -110,6 +110,7 @@ void QrScanThread::processVideoFrame(const QVideoFrame &frame)
void QrScanThread::stop()
{
m_running = false;
+ m_waitCondition.wakeOne();
}
void QrScanThread::addFrame(const QVideoFrame &frame)
@@ -124,9 +125,10 @@ void QrScanThread::run()
QVideoFrame frame;
while(m_running) {
QMutexLocker locker(&m_mutex);
- while(m_queue.isEmpty())
+ while(m_queue.isEmpty() && m_running)
m_waitCondition.wait(&m_mutex);
- processVideoFrame(m_queue.takeFirst());
+ if(!m_queue.isEmpty())
+ processVideoFrame(m_queue.takeFirst());
}
}
diff --git a/src/QR-Code-scanner/QrScanThread.h b/src/QR-Code-scanner/QrScanThread.h
index 03f17be3..296e1dc5 100644
--- a/src/QR-Code-scanner/QrScanThread.h
+++ b/src/QR-Code-scanner/QrScanThread.h
@@ -44,6 +44,7 @@ class QrScanThread : public QThread, public zbar::Image::Handler
public:
QrScanThread(QObject *parent = Q_NULLPTR);
void addFrame(const QVideoFrame &frame);
+ virtual void stop();
Q_SIGNALS:
void decoded(int type, const QString &data);
@@ -51,7 +52,6 @@ Q_SIGNALS:
protected:
virtual void run();
- virtual void stop();
void processVideoFrame(const QVideoFrame &);
void processQImage(const QImage &);
void processZImage(zbar::Image &image);
diff --git a/src/libwalletqt/TransactionInfo.cpp b/src/libwalletqt/TransactionInfo.cpp
index 5ad739bf..a787b151 100644
--- a/src/libwalletqt/TransactionInfo.cpp
+++ b/src/libwalletqt/TransactionInfo.cpp
@@ -38,6 +38,8 @@ QString TransactionInfo::displayAmount() const
QString TransactionInfo::fee() const
{
+ if(m_pimpl->fee() == 0)
+ return "";
return WalletManager::instance()->displayAmount(m_pimpl->fee());
}
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index 409d3d1a..e5ffef82 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -646,6 +646,8 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
Wallet::~Wallet()
{
qDebug("~Wallet: Closing wallet");
+ delete m_addressBook;
+ m_addressBook = NULL;
delete m_history;
m_history = NULL;
diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp
index 396274c6..a8346478 100644
--- a/src/libwalletqt/WalletManager.cpp
+++ b/src/libwalletqt/WalletManager.cpp
@@ -275,6 +275,11 @@ bool WalletManager::stopMining()
return m_pimpl->stopMining();
}
+bool WalletManager::localDaemonSynced() const
+{
+ return blockchainHeight() > 1 && blockchainHeight() >= blockchainTargetHeight();
+}
+
QString WalletManager::resolveOpenAlias(const QString &address) const
{
bool dnssec_valid = false;
diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h
index bf9bf19a..69c63b05 100644
--- a/src/libwalletqt/WalletManager.h
+++ b/src/libwalletqt/WalletManager.h
@@ -112,6 +112,7 @@ public:
Q_INVOKABLE quint64 blockchainHeight() const;
Q_INVOKABLE quint64 blockchainTargetHeight() const;
Q_INVOKABLE double miningHashRate() const;
+ Q_INVOKABLE bool localDaemonSynced() const;
Q_INVOKABLE bool isMining() const;
Q_INVOKABLE bool startMining(const QString &address, quint32 threads, bool backgroundMining, bool ignoreBattery);
diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml
index 99ee2478..14142212 100644
--- a/wizard/WizardCreateWallet.qml
+++ b/wizard/WizardCreateWallet.qml
@@ -78,7 +78,7 @@ ColumnLayout {
// 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 settingsObject.wallet !== 'undefined') {
+ if (typeof m_wallet !== 'undefined') {
walletManager.closeWallet()
console.log("deleting wallet")
}
@@ -91,8 +91,8 @@ ColumnLayout {
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
- settingsObject.wallet = wallet
- settingsObject.tmp_wallet_filename = tmp_wallet_filename
+ m_wallet = wallet;
+ settingsObject['tmp_wallet_filename'] = tmp_wallet_filename
}
WizardManageWalletUI {
diff --git a/wizard/WizardDaemonSettings.qml b/wizard/WizardDaemonSettings.qml
new file mode 100644
index 00000000..db6d1f62
--- /dev/null
+++ b/wizard/WizardDaemonSettings.qml
@@ -0,0 +1,198 @@
+// 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 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
+ Behavior on opacity {
+ NumberAnimation { duration: 100; easing.type: Easing.InQuad }
+ }
+
+ onOpacityChanged: visible = opacity !== 0
+
+
+ function onPageOpened(settingsObject) {
+ }
+ function onWizardRestarted(){
+ }
+
+ function onPageClosed(settingsObject) {
+ appWindow.persistentSettings.useRemoteNode = remoteNode.checked
+ appWindow.persistentSettings.startLocalNode = localNode.checked
+ appWindow.persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
+ return true
+ }
+
+ RowLayout {
+ id: dotsRow
+ Layout.alignment: Qt.AlignRight
+
+ ListModel {
+ id: dotsModel
+ ListElement { dotColor: "#36B05B" }
+ ListElement { dotColor: "#36B05B" }
+ ListElement { dotColor: "#FFE00A" }
+ ListElement { dotColor: "#DBDBDB" }
+ }
+
+ Repeater {
+ 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: "Daemon settings"
+
+ }
+
+ Text {
+ Layout.fillWidth: true
+ Layout.topMargin: 30 * scaleRatio
+ Layout.bottomMargin: 30 * scaleRatio
+ font.family: "Arial"
+ font.pixelSize: 18 * scaleRatio
+ wrapMode: Text.Wrap
+ //renderType: Text.NativeRendering
+ color: "#4A4646"
+ textFormat: Text.RichText
+// horizontalAlignment: Text.AlignHCenter
+ text: qsTr("To be able to communicate with the Monero network your wallet needs to be connected to a Monero node. For best privacy it's recommended to run your own node. \
+
\
+ If you don't have the option to run an own node there's an option to connect to a remote node.")
+ + translationManager.emptyString
+ }
+ }
+
+ ColumnLayout {
+
+ RowLayout {
+ CheckBox {
+ id: localNode
+ text: qsTr("Start a node automatically in background (recommended)") + translationManager.emptyString
+ background: "#FFFFFF"
+ fontColor: "#4A4646"
+ fontSize: 16 * scaleRatio
+ checkedIcon: "../images/checkedVioletIcon.png"
+ uncheckedIcon: "../images/uncheckedIcon.png"
+ checked: appWindow.persistentSettings.startLocalNode && !isAndroid && !isIOS
+ visible: !isAndroid && !isIOS
+ }
+ }
+
+ ColumnLayout {
+ visible: localNode.checked
+ id: blockchainFolderRow
+ Label {
+ Layout.fillWidth: true
+ Layout.topMargin: 20 * scaleRatio
+ fontSize: 14 * scaleRatio
+ text: qsTr("Blockchain location") + translationManager.emptyString
+ }
+ LineEdit {
+ id: blockchainFolder
+ Layout.preferredWidth: 200 * scaleRatio
+ Layout.fillWidth: true
+ text: persistentSettings.blockchainDataDir
+ placeholderText: qsTr("(optional)") + translationManager.emptyString
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ mouse.accepted = false
+ if(persistentSettings.blockchainDataDir != "")
+ blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir
+ blockchainFileDialog.open()
+ blockchainFolder.focus = true
+ }
+ }
+
+ }
+ }
+
+ RowLayout {
+ CheckBox {
+ id: remoteNode
+ text: (localNode.checked) ? qsTr("Connect to a remote node until my own node has finished syncing") + translationManager.emptyString
+ : qsTr("Connect to a remote node") + translationManager.emptyString
+ Layout.topMargin: 20 * scaleRatio
+ background: "#FFFFFF"
+ fontColor: "#4A4646"
+ fontSize: 16 * scaleRatio
+ checkedIcon: "../images/checkedVioletIcon.png"
+ uncheckedIcon: "../images/uncheckedIcon.png"
+ checked: appWindow.persistentSettings.useRemoteNode
+ }
+
+ }
+
+ RowLayout {
+ RemoteNodeEdit {
+ Layout.minimumWidth: 300 * scaleRatio
+ opacity: remoteNode.checked
+ id: remoteNodeEdit
+ daemonAddrText: persistentSettings.remoteNodeAddress.split(":")[0].trim()
+ daemonPortText: (persistentSettings.remoteNodeAddress.split(":")[1].trim() == "") ? "18081" : persistentSettings.remoteNodeAddress.split(":")[1]
+ }
+ }
+ }
+
+
+ Component.onCompleted: {
+ parent.wizardRestarted.connect(onWizardRestarted)
+ }
+}
diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml
index a6999e9c..794a5cf9 100644
--- a/wizard/WizardFinish.qml
+++ b/wizard/WizardFinish.qml
@@ -100,7 +100,7 @@ ColumnLayout {
ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#36B05B" }
- //ListElement { dotColor: "#36B05B" }
+ ListElement { dotColor: "#FFE00A" }
}
Repeater {
@@ -120,7 +120,7 @@ ColumnLayout {
Text {
Layout.fillWidth: true
font.family: "Arial"
- font.pixelSize: 28
+ font.pixelSize: 28 * scaleRatio
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
//renderType: Text.NativeRendering
@@ -132,7 +132,7 @@ ColumnLayout {
Layout.fillWidth: true
id: settingsText
font.family: "Arial"
- font.pixelSize: 16
+ font.pixelSize: 16 * scaleRatio
wrapMode: Text.Wrap
textFormat: Text.RichText
horizontalAlignment: Text.AlignHLeft
diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml
index 1b16acfd..d5c9eb11 100644
--- a/wizard/WizardMain.qml
+++ b/wizard/WizardMain.qml
@@ -40,17 +40,19 @@ ColumnLayout {
property alias nextButton : nextButton
property var settings : ({})
property int currentPage: 0
- property int wizardLeftMargin: (!isMobile) ? 150 : 25
- property int wizardRightMargin: (!isMobile) ? 150 : 25
- property int wizardBottomMargin: (isMobile) ? 150 : 25
- property int wizardTopMargin: (isMobile) ? 15 : 50
+ 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, finishPage ],
- "recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, finishPage ],
+ "create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, daemonSettingsPage, finishPage ],
+ "recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, daemonSettingsPage, finishPage ],
"create_view_only_wallet" : [ createViewOnlyWalletPage, passwordPage ],
}
@@ -81,6 +83,10 @@ ColumnLayout {
}
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) {
@@ -130,6 +136,8 @@ ColumnLayout {
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);
@@ -137,9 +145,8 @@ ColumnLayout {
function openOpenWalletPage() {
console.log("open wallet from file page");
- if (typeof wizard.settings['wallet'] !== 'undefined') {
- settings.wallet.destroy();
- delete wizard.settings['wallet'];
+ if (typeof m_wallet !== 'undefined' && m_wallet != null) {
+ walletManager.closeWallet()
}
optionsPage.onPageClosed(settings)
wizard.openWalletFromFileClicked();
@@ -203,11 +210,10 @@ ColumnLayout {
var new_wallet_filename = createWalletPath(settings.wallet_path,settings.account_name)
if(isIOS) {
console.log("saving in ios: "+ moneroAccountsDir + new_wallet_filename)
- settings.wallet.store(moneroAccountsDir + new_wallet_filename);
+ m_wallet.store(moneroAccountsDir + new_wallet_filename);
} else {
console.log("saving in wizard: "+ new_wallet_filename)
- settings.wallet.store(new_wallet_filename);
-
+ m_wallet.store(new_wallet_filename);
}
@@ -217,7 +223,7 @@ ColumnLayout {
oshelper.removeTemporaryWallet(settings.tmp_wallet_filename)
// protecting wallet with password
- settings.wallet.setPassword(settings.wallet_password);
+ m_wallet.setPassword(settings.wallet_password);
// Store password in session to be able to use password protected functions (e.g show seed)
appWindow.password = settings.wallet_password
@@ -291,6 +297,12 @@ ColumnLayout {
Layout.topMargin: wizardTopMargin
}
+ WizardDaemonSettings {
+ id: daemonSettingsPage
+ Layout.bottomMargin: wizardBottomMargin
+ Layout.topMargin: wizardTopMargin
+ }
+
WizardDonation {
id: donationPage
Layout.bottomMargin: wizardBottomMargin
@@ -308,10 +320,10 @@ ColumnLayout {
anchors.verticalCenter: wizard.verticalCenter
anchors.left: parent.left
anchors.leftMargin: isMobile ? 20 : 50
- anchors.bottomMargin: isMobile ? 20 : 50
+ anchors.bottomMargin: isMobile ? 20 * scaleRatio : 50
visible: parent.currentPage > 0
- width: 50; height: 50
+ width: 50 * scaleRatio; height: 50 * scaleRatio
radius: 25
color: prevArea.containsMouse ? "#FF4304" : "#FF6C3C"
@@ -333,10 +345,10 @@ ColumnLayout {
id: nextButton
anchors.verticalCenter: wizard.verticalCenter
anchors.right: parent.right
- anchors.rightMargin: isMobile ? 20 : 50
- anchors.bottomMargin: isMobile ? 20 : 50
+ anchors.rightMargin: isMobile ? 20 * scaleRatio : 50
+ anchors.bottomMargin: isMobile ? 20 * scaleRatio : 50
visible: currentPage > 1 && currentPage < pages.length - 1
- width: 50; height: 50
+ width: 50 * scaleRatio; height: 50 * scaleRatio
radius: 25
color: enabled ? nextArea.containsMouse ? "#FF4304" : "#FF6C3C" : "#DBDBDB"
@@ -359,7 +371,7 @@ ColumnLayout {
id: sendButton
anchors.right: parent.right
anchors.bottom: parent.bottom
- anchors.margins: (isMobile) ? 20 : 50
+ anchors.margins: (isMobile) ? 20 * scaleRatio : 50 * scaleRatio
text: qsTr("USE MONERO") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -376,7 +388,7 @@ ColumnLayout {
id: createViewOnlyWalletButton
anchors.right: parent.right
anchors.bottom: parent.bottom
- anchors.margins: (isMobile) ? 20 : 50
+ anchors.margins: (isMobile) ? 20 * scaleRatio : 50
text: qsTr("Create wallet") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -408,7 +420,7 @@ ColumnLayout {
id: abortViewOnlyButton
anchors.right: createViewOnlyWalletButton.left
anchors.bottom: parent.bottom
- anchors.margins: (isMobile) ? 20 : 50
+ anchors.margins: (isMobile) ? 20 * scaleRatio : 50
text: qsTr("Abort") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml
index 9b3f206d..fb714ad0 100644
--- a/wizard/WizardManageWalletUI.qml
+++ b/wizard/WizardManageWalletUI.qml
@@ -86,6 +86,31 @@ ColumnLayout {
return wordsArray.length === 25
}
+ 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
@@ -93,8 +118,8 @@ ColumnLayout {
ListModel {
id: dotsModel
- ListElement { dotColor: "#36B05B" }
- //ListElement { dotColor: "#DBDBDB" }
+ ListElement { dotColor: "#FFE00A" }
+ ListElement { dotColor: "#DBDBDB" }
ListElement { dotColor: "#DBDBDB" }
ListElement { dotColor: "#DBDBDB" }
}
@@ -118,7 +143,7 @@ ColumnLayout {
horizontalAlignment: Text.AlignHCenter
id: titleText
font.family: "Arial"
- font.pixelSize: 28
+ font.pixelSize: 28 * scaleRatio
wrapMode: Text.Wrap
color: "#3F3F3F"
}
@@ -128,8 +153,8 @@ ColumnLayout {
Layout.bottomMargin: rowSpacing
Label {
- Layout.topMargin: 20
- fontSize: 14
+ Layout.topMargin: 20 * scaleRatio
+ fontSize: 14 * scaleRatio
text: qsTr("Wallet name")
+ translationManager.emptyString
}
@@ -137,16 +162,17 @@ ColumnLayout {
LineEdit {
id: accountName
Layout.fillWidth: true
- Layout.maximumWidth: 600
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 600 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
text: defaultAccountName
onTextUpdated: checkNextButton()
}
}
- RowLayout{
+ GridLayout{
+ columns: (isMobile)? 2 : 4
visible: recoverMode
- spacing: 0
+
StandardButton {
id: recoverFromSeedButton
text: qsTr("Restore from seed") + translationManager.emptyString
@@ -174,6 +200,22 @@ ColumnLayout {
checkNextButton();
}
}
+
+ StandardButton {
+ id: qrfinderButton
+ text: qsTr("From QR Code") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ visible : true //appWindow.qrScannerEnabled
+ enabled : visible
+ onClicked: {
+ cameraUi.state = "Capture"
+ cameraUi.qrcode_decoded.connect(updateFromQrCode)
+ }
+ }
+
}
// Recover from seed
@@ -183,8 +225,8 @@ ColumnLayout {
WizardMemoTextInput {
id : memoTextItem
Layout.fillWidth: true
- Layout.maximumWidth: 600
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 600 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
}
}
@@ -198,24 +240,24 @@ ColumnLayout {
LineEdit {
Layout.fillWidth: true
id: addressLine
- Layout.maximumWidth: 600
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 600 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
placeholderText: qsTr("Account address (public)") + translationManager.emptyString
onTextUpdated: checkNextButton()
}
LineEdit {
Layout.fillWidth: true
id: viewKeyLine
- Layout.maximumWidth: 600
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 600 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
placeholderText: qsTr("View key (private)") + translationManager.emptyString
onTextUpdated: checkNextButton()
}
LineEdit {
Layout.fillWidth: true
- Layout.maximumWidth: 600
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 600 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
id: spendKeyLine
placeholderText: qsTr("Spend key (private)") + translationManager.emptyString
onTextUpdated: checkNextButton()
@@ -227,8 +269,8 @@ ColumnLayout {
LineEdit {
id: restoreHeightItem
Layout.fillWidth: true
- Layout.maximumWidth: 600
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 600 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
placeholderText: qsTr("Restore height (optional)") + translationManager.emptyString
validator: IntValidator {
bottom:0
@@ -240,15 +282,15 @@ ColumnLayout {
ColumnLayout {
Label {
Layout.fillWidth: true
- Layout.topMargin: 20
+ Layout.topMargin: 20 * scaleRatio
fontSize: 14
text: qsTr("Your wallet is stored in") + ": " + fileUrlInput.text;
}
LineEdit {
Layout.fillWidth: true
- Layout.maximumWidth: 600
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 600 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
id: fileUrlInput
text: moneroAccountsDir + "/"
diff --git a/wizard/WizardMemoTextInput.qml b/wizard/WizardMemoTextInput.qml
index e9fbfdc9..d278508e 100644
--- a/wizard/WizardMemoTextInput.qml
+++ b/wizard/WizardMemoTextInput.qml
@@ -25,21 +25,21 @@ Column {
TextEdit {
id: memoTextInput
property alias placeholderText: memoTextPlaceholder.text
- textMargin: 8
+ textMargin: 8 * scaleRatio
text: ""
font.family: "Arial"
- font.pixelSize: 16
+ font.pixelSize: 16 * scaleRatio
wrapMode: TextInput.Wrap
width: parent.width
selectByMouse: true
- property int minimumHeight: 100
+ property int minimumHeight: 100 * scaleRatio
height: contentHeight > minimumHeight ? contentHeight : minimumHeight
Text {
id: memoTextPlaceholder
anchors.fill:parent
- font.pixelSize: 16
- anchors.margins: 8
+ font.pixelSize: 16 * scaleRatio
+ anchors.margins: 8 * scaleRatio
font.bold:true
text: qsTr("Enter your 25 word mnemonic seed") + translationManager.emptyString
color: "#BABABA"
@@ -59,7 +59,11 @@ Column {
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
- onClicked: clipboard.setText(memoTextInput.text)
+ onClicked: {
+ clipboard.setText(memoTextInput.text)
+ appWindow.showStatusMessage(qsTr("Seed copied to clipboard"),3)
+ }
+
}
}
Rectangle {
@@ -75,14 +79,14 @@ Column {
Text {
id: wordsTipText
anchors.fill: parent
- anchors.topMargin : 16
- anchors.bottomMargin: 16
- anchors.leftMargin: 16
- anchors.rightMargin: 16
+ 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
+ font.pixelSize: 15 * scaleRatio
color: "#4A4646"
wrapMode: Text.Wrap
text: qsTr("This seed is very important to write down and keep secret. It is all you need to backup and restore your wallet.")
diff --git a/wizard/WizardOptions.qml b/wizard/WizardOptions.qml
index 0154b9ce..8f4e9477 100644
--- a/wizard/WizardOptions.qml
+++ b/wizard/WizardOptions.qml
@@ -38,8 +38,8 @@ ColumnLayout {
signal openWalletClicked()
opacity: 0
visible: false
- property int buttonSize: (isMobile) ? 80 : 190
- property int buttonImageSize: (isMobile) ? buttonSize - 10 : buttonSize - 30
+ property int buttonSize: (isMobile) ? 80 * scaleRatio : 190 * scaleRatio
+ property int buttonImageSize: (isMobile) ? buttonSize - 10 * scaleRatio : buttonSize - 30 * scaleRatio
function onPageClosed() {
// Save settings used in open from file.
@@ -60,13 +60,13 @@ ColumnLayout {
id: headerColumn
Layout.leftMargin: wizardLeftMargin
Layout.rightMargin: wizardRightMargin
- Layout.bottomMargin: (!isMobile) ? 40 : 20
- spacing: 30
+ Layout.bottomMargin: (!isMobile) ? 40 * scaleRatio : 20
+ spacing: 30 * scaleRatio
Text {
Layout.fillWidth: true
font.family: "Arial"
- font.pixelSize: 28
+ font.pixelSize: 28 * scaleRatio
//renderType: Text.NativeRendering
color: "#3F3F3F"
wrapMode: Text.Wrap
@@ -77,7 +77,7 @@ ColumnLayout {
Text {
Layout.fillWidth: true
font.family: "Arial"
- font.pixelSize: 18
+ font.pixelSize: 18 * scaleRatio
//renderType: Text.NativeRendering
color: "#4A4646"
wrapMode: Text.Wrap
@@ -91,8 +91,8 @@ ColumnLayout {
Layout.rightMargin: wizardRightMargin
Layout.alignment: Qt.AlignCenter
id: actionButtons
- columnSpacing: 40
- rowSpacing: 10
+ columnSpacing: 40 * scaleRatio
+ rowSpacing: 10 * scaleRatio
Layout.fillWidth: true
Layout.fillHeight: true
flow: isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
@@ -101,8 +101,8 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
- rowSpacing: 20
- columnSpacing: 10
+ rowSpacing: 20 * scaleRatio
+ columnSpacing: 10 * scaleRatio
Rectangle {
Layout.preferredHeight: page.buttonSize
@@ -132,9 +132,9 @@ ColumnLayout {
}
Text {
- Layout.preferredWidth: 190
+ Layout.preferredWidth: page.buttonSize
font.family: "Arial"
- font.pixelSize: 16
+ font.pixelSize: 16 * scaleRatio
color: "#4A4949"
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
@@ -146,8 +146,8 @@ ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
- rowSpacing: 20
- columnSpacing: 10
+ rowSpacing: 20 * scaleRatio
+ columnSpacing: 10 * scaleRatio
Rectangle {
Layout.preferredHeight: page.buttonSize
@@ -156,7 +156,7 @@ ColumnLayout {
color: recoverWalletArea.containsMouse ? "#DBDBDB" : "#FFFFFF"
Image {
- width: page.buttomImageSize
+ width: page.buttonImageSize
height: page.buttonImageSize
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
@@ -174,9 +174,9 @@ ColumnLayout {
}
Text {
- Layout.preferredWidth: 190
+ Layout.preferredWidth: page.buttonSize
font.family: "Arial"
- font.pixelSize: 16
+ font.pixelSize: 16 * scaleRatio
color: "#4A4949"
horizontalAlignment: Text.AlignHCenter
text: qsTr("Restore wallet from keys or mnemonic seed") + translationManager.emptyString
@@ -189,8 +189,8 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
- rowSpacing: 20
- columnSpacing: 10
+ rowSpacing: 20 * scaleRatio
+ columnSpacing: 10 * scaleRatio
Rectangle {
Layout.preferredHeight: page.buttonSize
@@ -217,9 +217,9 @@ ColumnLayout {
}
Text {
- Layout.preferredWidth: 190
+ Layout.preferredWidth: page.buttonSize
font.family: "Arial"
- font.pixelSize: 16
+ font.pixelSize: 16 * scaleRatio
color: "#4A4949"
horizontalAlignment: Text.AlignHCenter
text: qsTr("Open a wallet from file") + translationManager.emptyString
@@ -234,18 +234,18 @@ ColumnLayout {
RowLayout {
Layout.leftMargin: wizardLeftMargin
Layout.rightMargin: wizardRightMargin
- Layout.topMargin: 30
+ Layout.topMargin: 30 * scaleRatio
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
Rectangle {
- width: 100
+ width: 100 * scaleRatio
CheckBox {
id: testNet
text: qsTr("Testnet") + translationManager.emptyString
background: "#FFFFFF"
fontColor: "#4A4646"
- fontSize: 16
+ fontSize: 16 * scaleRatio
checkedIcon: "../images/checkedVioletIcon.png"
uncheckedIcon: "../images/uncheckedIcon.png"
checked: appWindow.persistentSettings.testnet;
diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml
index 2444add0..3ce6584d 100644
--- a/wizard/WizardPassword.qml
+++ b/wizard/WizardPassword.qml
@@ -64,7 +64,6 @@ ColumnLayout {
function onPageClosed(settingsObject) {
// TODO: set password on the final page
- // settingsObject.wallet.setPassword(passwordItem.password)
settingsObject['wallet_password'] = passwordUI.password
return true
}
@@ -82,8 +81,8 @@ ColumnLayout {
ListModel {
id: dotsModel
ListElement { dotColor: "#36B05B" }
- ListElement { dotColor: "#36B05B" }
- //ListElement { dotColor: "#FFE00A" }
+ ListElement { dotColor: "#FFE00A" }
+ ListElement { dotColor: "#DBDBDB" }
ListElement { dotColor: "#DBDBDB" }
}
@@ -107,7 +106,7 @@ ColumnLayout {
Layout.fillWidth: true
id: titleText
font.family: "Arial"
- font.pixelSize: 28
+ font.pixelSize: 28 * scaleRatio
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
//renderType: Text.NativeRendering
@@ -117,9 +116,9 @@ ColumnLayout {
Text {
Layout.fillWidth: true
- Layout.bottomMargin: 30
+ Layout.bottomMargin: 30 * scaleRatio
font.family: "Arial"
- font.pixelSize: 18
+ font.pixelSize: 18 * scaleRatio
wrapMode: Text.Wrap
//renderType: Text.NativeRendering
color: "#4A4646"
diff --git a/wizard/WizardPasswordInput.qml b/wizard/WizardPasswordInput.qml
index 6be2f618..a2651440 100644
--- a/wizard/WizardPasswordInput.qml
+++ b/wizard/WizardPasswordInput.qml
@@ -42,7 +42,7 @@ ColumnLayout {
id : password
focus:true
font.family: "Arial"
- font.pixelSize: (isMobile) ? 25 : 26
+ font.pixelSize: (isMobile) ? 25 * scaleRatio : 26 * scaleRatio
echoMode: TextInput.Password
style: TextFieldStyle {
renderType: Text.NativeRendering
diff --git a/wizard/WizardPasswordUI.qml b/wizard/WizardPasswordUI.qml
index c8e98905..bca911b8 100644
--- a/wizard/WizardPasswordUI.qml
+++ b/wizard/WizardPasswordUI.qml
@@ -42,19 +42,22 @@ ColumnLayout {
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)
+ // 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() {
@@ -64,8 +67,8 @@ ColumnLayout {
WizardPasswordInput {
id: passwordItem
Layout.fillWidth: true
- Layout.maximumWidth: 300
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 300 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
Layout.alignment: Qt.AlignHCenter
placeholderText : qsTr("Password") + translationManager.emptyString;
KeyNavigation.tab: retypePasswordItem
@@ -76,8 +79,8 @@ ColumnLayout {
WizardPasswordInput {
id: retypePasswordItem
Layout.fillWidth: true
- Layout.maximumWidth: 300
- Layout.minimumWidth: 200
+ Layout.maximumWidth: 300 * scaleRatio
+ Layout.minimumWidth: 200 * scaleRatio
Layout.alignment: Qt.AlignHCenter
placeholderText : qsTr("Confirm password") + translationManager.emptyString;
KeyNavigation.tab: passwordItem
@@ -85,7 +88,8 @@ ColumnLayout {
}
PrivacyLevelSmall {
- Layout.topMargin: isMobile ? 20 : 40
+ visible: !isAndroid //TODO: strength meter doesnt work on Android
+ Layout.topMargin: isAndroid ? 20 * scaleRatio : 40 * scaleRatio
Layout.fillWidth: true
id: privacyLevel
background: "#F0EEEE"
diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml
index 240641e0..acf0caea 100644
--- a/wizard/WizardRecoveryWallet.qml
+++ b/wizard/WizardRecoveryWallet.qml
@@ -81,6 +81,12 @@ ColumnLayout {
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, testnet, restoreHeight)
@@ -92,7 +98,7 @@ ColumnLayout {
var success = wallet.status === Wallet.Status_Ok;
if (success) {
- settingsObject['wallet'] = wallet;
+ m_wallet = wallet;
settingsObject['is_recovering'] = true;
settingsObject['tmp_wallet_filename'] = tmp_wallet_filename
} else {
diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml
index 8b440092..32249cb1 100644
--- a/wizard/WizardWelcome.qml
+++ b/wizard/WizardWelcome.qml
@@ -60,13 +60,13 @@ ColumnLayout {
id: headerColumn
Layout.leftMargin: wizardLeftMargin
Layout.rightMargin: wizardRightMargin
- Layout.bottomMargin: 40
- spacing: 20
+ Layout.bottomMargin: 40 * scaleRatio
+ spacing: 20 * scaleRatio
Text {
Layout.fillWidth: true
font.family: "Arial"
- font.pixelSize: 28
+ font.pixelSize: 28 * scaleRatio
color: "#3F3F3F"
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
@@ -76,7 +76,7 @@ ColumnLayout {
Text {
Layout.fillWidth: true
font.family: "Arial"
- font.pixelSize: 18
+ font.pixelSize: 18 * scaleRatio
color: "#4A4646"
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
@@ -116,17 +116,16 @@ ColumnLayout {
property int margin: (isMobile) ? 0 : Math.floor(appWindow.width/12);
id: gridView
- cellWidth: 140
- cellHeight: 120
+ cellWidth: 140 * scaleRatio
+ cellHeight: 120 * scaleRatio
model: languagesModel
// Hack to center the flag grid
- property int columns: Math.floor(appWindow.width/140)
- Layout.leftMargin: margin + (appWindow.width - cellWidth*columns) /2
+ 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: ColumnLayout {
@@ -136,9 +135,9 @@ ColumnLayout {
// Layout.alignment: Qt.AlignHCenter
Rectangle {
id: flagRect
- width: 60; height: 60
+ width: 60 * scaleRatio; height: 60 * scaleRatio
// anchors.centerIn: parent
- radius: 30
+ radius: 30 * scaleRatio
Layout.alignment: Qt.AlignHCenter
color: gridView.currentIndex === index ? "#DBDBDB" : "#FFFFFF"
Image {
@@ -149,7 +148,7 @@ ColumnLayout {
Text {
font.family: "Arial"
- font.pixelSize: 18
+ font.pixelSize: 18 * scaleRatio
// anchors.horizontalCenter: parent.horizontalCenter
font.bold: gridView.currentIndex === index
// elide: Text.ElideRight