diff --git a/components/AddressBookTable.qml b/components/AddressBookTable.qml
deleted file mode 100644
index adc4aec9..00000000
--- a/components/AddressBookTable.qml
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2014-2018, The Monero Project
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification, are
-// permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this list of
-// conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice, this list
-// of conditions and the following disclaimer in the documentation and/or other
-// materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its contributors may be
-// used to endorse or promote products derived from this software without specific
-// prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import QtQuick 2.0
-import moneroComponents.Clipboard 1.0
-import "../js/TxUtils.js" as TxUtils
-
-ListView {
- id: listView
- clip: true
- boundsBehavior: ListView.StopAtBounds
- property bool selectAndSend: false
-
- footer: Rectangle {
- height: 127
- width: listView.width
- color: "transparent"
-
- Text {
- anchors.centerIn: parent
- font.family: "Arial"
- font.pixelSize: 14
- color: "#808080"
- text: qsTr("No more results") + translationManager.emptyString
- }
- }
-
- property var previousItem
- delegate: Rectangle {
- id: delegate
- height: 64
- width: listView.width
- color: "transparent"
- z: listView.count - index
- function collapseDropdown() { dropdown.expanded = false }
- function doSend() {
- console.log("Sending to: ", address +" "+ paymentId);
- middlePanel.sendTo(address, paymentId, description);
- leftPanel.selectItem(middlePanel.state)
- }
-
- Text {
- id: descriptionText
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.topMargin: 12
- width: text.length ? (descriptionArea.containsMouse ? 139 : 139) : 0
- font.family: "Arial"
- font.bold: true
- font.pixelSize: 19
- color: "#ffffff"
- elide: Text.ElideRight
- text: description
- textFormat: Text.PlainText
-
- MouseArea {
- id: descriptionArea
- anchors.fill: parent
- hoverEnabled: true
- }
- }
-
- TextEdit {
- id: addressText
- selectByMouse: true
- anchors.bottom: descriptionText.bottom
- anchors.left: descriptionText.right
- anchors.right: dropdown.left
- anchors.leftMargin: description.length > 0 ? 12 : 0
- anchors.rightMargin: 40
- font.family: "Arial"
- font.pixelSize: 16
- color: "#ffffff"
- text: {
- if(isMobile){
- TxUtils.addressTruncate(address, 6);
- } else {
- return TxUtils.addressTruncate(address, 10);
- }
- }
- readOnly: true
- }
-
- Text {
- id: paymentLabel
- anchors.left: parent.left
- anchors.bottom: parent.bottom
- anchors.bottomMargin: 12
-
- width: 139
- font.family: "Arial"
- font.pixelSize: 12
- color: "#ffffff"
- text: qsTr("Payment ID:") + translationManager.emptyString
- }
-
- TextEdit {
- selectByMouse: true;
- anchors.bottom: paymentLabel.bottom
- anchors.left: paymentLabel.right
- anchors.leftMargin: 12
- anchors.rightMargin: 12
- anchors.right: dropdown.left
- readOnly: true
-
- font.family: "Arial"
- font.pixelSize: 13
- color: "#545454"
- text: {
- if(isMobile){
- TxUtils.addressTruncate(paymentId, 6);
- } else {
- return TxUtils.addressTruncate(paymentId, 10);
- }
- }
- }
-
- ListModel {
- id: dropModel
- ListElement { name: "Copy address to clipboard"; icon: "../images/dropdownCopy.png" }
- ListElement { name: "Send to this address"; icon: "../images/dropdownSend.png" }
-// ListElement { name: "Find similar transactions"; icon: "../images/dropdownSearch.png" }
- ListElement { name: "Remove from address book"; icon: "../images/dropdownDel.png" }
- }
-
- Clipboard { id: clipboard }
- TableDropdown {
- id: dropdown
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.rightMargin: 5
- dataModel: dropModel
- visible: !listView.selectAndSend
- z: 1
- onExpandedChanged: {
- if(expanded) {
- listView.previousItem = delegate
- listView.currentIndex = index
- }
- }
- onOptionClicked: {
- // Ensure tooltip is closed
- appWindow.toolTip.visible = false;
- if(option === 0) {
- clipboard.setText(address)
- appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3)
- }
- else if(option === 1){
- doSend()
- } else if(option === 2){
- console.log("Delete: ", rowId);
- currentWallet.addressBookModel.deleteRow(rowId);
- }
- }
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- height: 1
- color: "#404040"
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- visible: listView.selectAndSend
- onClicked: {
- doSend();
- }
- }
- }
-}
diff --git a/components/Style.qml b/components/Style.qml
index cc106239..8555cb5e 100644
--- a/components/Style.qml
+++ b/components/Style.qml
@@ -8,6 +8,11 @@ QtObject {
property QtObject fontLight: FontLoader { id: _fontLight; source: "qrc:/fonts/Roboto-Light.ttf"; }
property QtObject fontRegular: FontLoader { id: _fontRegular; source: "qrc:/fonts/Roboto-Regular.ttf"; }
+ property QtObject fontMonoMedium: FontLoader { id: _fontMonoMedium; source: "qrc:/fonts/RobotoMono-Medium.ttf"; }
+ property QtObject fontMonoBold: FontLoader { id: _fontMonoBold; source: "qrc:/fonts/RobotoMono-Bold.ttf"; }
+ property QtObject fontMonoLight: FontLoader { id: _fontMonoLight; source: "qrc:/fonts/RobotoMono-Light.ttf"; }
+ property QtObject fontMonoRegular: FontLoader { id: _fontMonoRegular; source: "qrc:/fonts/RobotoMono-Regular.ttf"; }
+
property string grey: "#404040"
property string orange: "#FF6C3C"
property string white: "#FFFFFF"
@@ -17,6 +22,7 @@ QtObject {
property string defaultFontColor: "white"
property string dimmedFontColor: "#BBBBBB"
property string lightGreyFontColor: "#DFDFDF"
+ property string greyFontColor: "#808080"
property string warningColor: "#963E00"
property string errorColor: "#FA6800"
property string inputBoxBackground: "black"
diff --git a/fonts/RobotoMono-Bold.ttf b/fonts/RobotoMono-Bold.ttf
new file mode 100755
index 00000000..61842afd
Binary files /dev/null and b/fonts/RobotoMono-Bold.ttf differ
diff --git a/fonts/RobotoMono-Light.ttf b/fonts/RobotoMono-Light.ttf
new file mode 100755
index 00000000..81563d86
Binary files /dev/null and b/fonts/RobotoMono-Light.ttf differ
diff --git a/fonts/RobotoMono-Medium.ttf b/fonts/RobotoMono-Medium.ttf
new file mode 100755
index 00000000..f40bc588
Binary files /dev/null and b/fonts/RobotoMono-Medium.ttf differ
diff --git a/fonts/RobotoMono-Regular.ttf b/fonts/RobotoMono-Regular.ttf
new file mode 100755
index 00000000..f7b4a9b3
Binary files /dev/null and b/fonts/RobotoMono-Regular.ttf differ
diff --git a/images/arrow-right-in-circle.png b/images/arrow-right-in-circle.png
new file mode 100755
index 00000000..0d19f08e
Binary files /dev/null and b/images/arrow-right-in-circle.png differ
diff --git a/images/arrow-right-in-circle@2x.png b/images/arrow-right-in-circle@2x.png
new file mode 100755
index 00000000..aa859b02
Binary files /dev/null and b/images/arrow-right-in-circle@2x.png differ
diff --git a/images/clipboard.png b/images/clipboard.png
new file mode 100755
index 00000000..8ab3d8de
Binary files /dev/null and b/images/clipboard.png differ
diff --git a/images/clipboard@2x.png b/images/clipboard@2x.png
new file mode 100755
index 00000000..02e2ec6d
Binary files /dev/null and b/images/clipboard@2x.png differ
diff --git a/images/dropdownDel.png b/images/dropdownDel.png
deleted file mode 100644
index 73af193f..00000000
Binary files a/images/dropdownDel.png and /dev/null differ
diff --git a/images/rename.png b/images/rename.png
new file mode 100755
index 00000000..25a9bf64
Binary files /dev/null and b/images/rename.png differ
diff --git a/images/rename@2x.png b/images/rename@2x.png
new file mode 100755
index 00000000..308a2809
Binary files /dev/null and b/images/rename@2x.png differ
diff --git a/js/TxUtils.js b/js/TxUtils.js
index e53424c6..fcd00ca3 100644
--- a/js/TxUtils.js
+++ b/js/TxUtils.js
@@ -17,6 +17,13 @@ function addressTruncate(address, range){
return address.substring(0, range) + "..." + address.substring(address.length-range);
}
+function addressTruncatePretty(address, blocks){
+ if(typeof(address) === "undefined") return;
+ if(typeof(blocks) === "undefined") blocks = 2;
+ var ret = "";
+ return address.substring(0, 4 * blocks).match(/.{1,4}/g).join(' ') + " .. " + address.substring(address.length - 4 * blocks).match(/.{1,4}/g).join(' ');
+}
+
function check256(str, length) {
if (str.length != length)
return false;
diff --git a/pages/AddressBook.qml b/pages/AddressBook.qml
index b8c7967c..2103b235 100644
--- a/pages/AddressBook.qml
+++ b/pages/AddressBook.qml
@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0
+import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import "../components" as MoneroComponents
@@ -35,231 +36,442 @@ import moneroComponents.AddressBook 1.0
import moneroComponents.AddressBookModel 1.0
import moneroComponents.Clipboard 1.0
import moneroComponents.NetworkType 1.0
+import FontAwesome 1.0
-ColumnLayout {
+Rectangle {
id: root
- property var model
+ color: "transparent"
property bool selectAndSend: false
+ property bool editEntry: false
+
Clipboard { id: clipboard }
ColumnLayout {
- Layout.margins: (isMobile ? 17 : 20) * scaleRatio
- Layout.topMargin: 40 * scaleRatio
- Layout.fillWidth: true
- spacing: 26 * scaleRatio
- visible: !root.selectAndSend
+ id: mainLayout
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
+ anchors.topMargin: 40 * scaleRatio
- MoneroComponents.LineEditMulti {
- id: addressLine
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.right: parent.right
+
+ spacing: 20 * scaleRatio
+
+ ColumnLayout {
+ id: addressBookEmptyLayout
+ visible: addressBookListView.count == 0
+ spacing: 0
Layout.fillWidth: true
- fontBold: true
- labelText: qsTr("Address") + translationManager.emptyString
- placeholderText: {
- switch (persistentSettings.nettype) {
- case NetworkType.MAINNET:
- return "4.. / 8.. / OpenAlias";
- case NetworkType.STAGENET:
- return "5.. / 7..";
- case NetworkType.TESTNET:
- return "9.. / B..";
- default:
- break;
+
+ TextArea {
+ id: titleLabel
+ Layout.fillWidth: true
+ color: MoneroComponents.Style.defaultFontColor
+ font.family: MoneroComponents.Style.fontRegular.name
+ font.pixelSize: 32 * scaleRatio
+ horizontalAlignment: TextInput.AlignLeft
+ selectByMouse: false
+ wrapMode: Text.WordWrap;
+ textMargin: 0
+ leftPadding: 0
+ topPadding: 0
+ text: qsTr("Save your most used addresses here") + translationManager.emptyString
+ width: parent.width
+ readOnly: true
+
+ // @TODO: Legacy. Remove after Qt 5.8.
+ // https://stackoverflow.com/questions/41990013
+ MouseArea {
+ anchors.fill: parent
+ enabled: false
}
}
- wrapMode: Text.WrapAnywhere
- addressValidation: true
- pasteButton: true
- onPaste: function(clipboardText) {
- const parsed = walletManager.parse_uri_to_object(clipboardText);
- if (!parsed.error) {
- addressLine.text = parsed.address;
- setPaymentId(parsed.payment_id);
- setDescription(parsed.tx_description);
- } else {
- addressLine.text = clipboardText;
+
+ TextArea {
+ Layout.fillWidth: true
+ color: MoneroComponents.Style.greyFontColor
+ font.family: MoneroComponents.Style.fontRegular.name
+ font.pixelSize: 16 * scaleRatio
+ horizontalAlignment: TextInput.AlignLeft
+ selectByMouse: false
+ wrapMode: Text.WordWrap;
+ textMargin: 0
+ leftPadding: 0
+ topPadding: 0
+ text: qsTr("This makes it easier to send or receive Monero and reduces errors when typing in addresses manually.") + translationManager.emptyString
+ width: parent.width
+ readOnly: true
+
+ // @TODO: Legacy. Remove after Qt 5.8.
+ // https://stackoverflow.com/questions/41990013
+ MouseArea {
+ anchors.fill: parent
+ enabled: false
}
}
- inlineButton.icon: "../images/qr.png"
- inlineButton.buttonColor: MoneroComponents.Style.orange
- inlineButton.onClicked: {
- cameraUi.state = "Capture"
- cameraUi.qrcode_decoded.connect(updateFromQrCode)
- }
- inlineButtonVisible : appWindow.qrScannerEnabled && !addressLine.text
- }
- MoneroComponents.StandardButton {
- id: resolveButton
- text: qsTr("Resolve") + translationManager.emptyString
- visible: TxUtils.isValidOpenAliasAddress(addressLine.text)
- enabled : visible
- 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.nettype)
- if (parts[0] === "true") {
- if (address_ok) {
- // prepend openalias to description
- descriptionLine.text = descriptionLine.text ? addressLine.text + " " + descriptionLine.text : addressLine.text
- addressLine.text = parts[1]
- }
- else
- oa_message(qsTr("No valid address found at this OpenAlias address"))
- }
- else if (parts[0] === "false") {
- if (address_ok) {
- addressLine.text = parts[1]
- 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("Internal error"))
- }
- }
- else {
- oa_message(qsTr("No address found"))
- }
- }
- }
-
- MoneroComponents.LineEditMulti {
- id: paymentIdLine
- visible: appWindow.persistentSettings.showPid
- Layout.fillWidth: true
- labelText: qsTr("Payment ID (Optional)") + translationManager.emptyString
- placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString
- wrapMode: Text.WrapAnywhere
-// 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
- }
-
- MoneroComponents.LineEditMulti {
- id: descriptionLine
- Layout.fillWidth: true
- labelText: qsTr("Description (Optional)") + translationManager.emptyString
- placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString
- wrapMode: Text.WrapAnywhere
- }
-
- RowLayout {
- id: addButton
- Layout.bottomMargin: 17 * scaleRatio
MoneroComponents.StandardButton {
- text: qsTr("Add") + translationManager.emptyString
- enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.nettype)
-
+ id: addFirstEntryButton
+ Layout.topMargin: 20
+ text: qsTr("Add an address") + 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
+ root.showAddAddress();
+ }
+ }
+ }
- informationPopup.onCloseCallback = null
- informationPopup.open();
+ ColumnLayout {
+ id: addressBookLayout
+ visible: addressBookListView.count >= 1
+ spacing: 0
+
+ MoneroComponents.Label {
+ Layout.bottomMargin: 20
+ fontSize: 32 * scaleRatio
+ text: qsTr("Address book") + translationManager.emptyString
+ }
+
+ ColumnLayout {
+ id: addressBookListRow
+ property int addressBookListItemHeight: 50 * scaleRatio
+ Layout.fillWidth: true
+ Layout.minimumWidth: 240
+ Layout.preferredHeight: addressBookListItemHeight * addressBookListView.count
+
+ ListView {
+ id: addressBookListView
+ Layout.fillWidth: true
+ anchors.fill: parent
+ clip: true
+ boundsBehavior: ListView.StopAtBounds
+ interactive: false
+ delegate: Rectangle {
+ id: tableItem2
+ height: addressBookListRow.addressBookListItemHeight
+ width: parent.width
+ Layout.fillWidth: true
+ color: "transparent"
+
+ function doSend() {
+ console.log("Sending to: ", address +" "+ paymentId);
+ middlePanel.sendTo(address, paymentId, description);
+ leftPanel.selectItem(middlePanel.state)
+ }
+
+ Rectangle {
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.top: parent.top
+ height: 1
+ color: MoneroComponents.Style.grey
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ anchors.topMargin: 5 * scaleRatio
+ anchors.rightMargin: 110 * scaleRatio
+ color: "transparent"
+
+ MoneroComponents.Label {
+ id: descriptionLabel
+ color: MoneroComponents.Style.defaultFontColor
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: 6 * scaleRatio
+ fontSize: 16 * scaleRatio
+ text: description
+ elide: Text.ElideRight
+ textWidth: addressLabel.x - descriptionLabel.x - 1
+ }
+
+ MoneroComponents.Label {
+ id: addressLabel
+ color: MoneroComponents.Style.defaultFontColor
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.right
+ anchors.leftMargin: -addressLabel.width - 5 * scaleRatio
+
+ fontSize: 16 * scaleRatio
+ fontFamily: MoneroComponents.Style.fontMonoRegular.name;
+ text: TxUtils.addressTruncatePretty(address, mainLayout.width < 540 ? 1 : (mainLayout.width < 700 ? 2 : 3));
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ visible: root.selectAndSend
+ onClicked: {
+ doSend();
+ }
+ }
+ }
+
+ MoneroComponents.IconButton {
+ id: sendToButton
+ imageSource: "../images/arrow-right-in-circle.png"
+ image.opacity: 0.5
+ anchors.right: parent.right
+ anchors.rightMargin: 63 * scaleRatio
+ onClicked: {
+ doSend();
+ }
+ }
+
+ MoneroComponents.IconButton {
+ id: renameButton
+ imageSource: "../images/rename.png"
+ image.opacity: 0.5
+ anchors.right: parent.right
+ anchors.rightMargin: 30 * scaleRatio
+ anchors.topMargin: 1 * scaleRatio
+
+ onClicked: {
+ addressBookListView.currentIndex = index;
+ root.showEditAddress(address, description);
+ }
+ }
+
+ MoneroComponents.IconButton {
+ id: copyButton
+ imageSource: "../images/clipboard.png"
+ image.opacity: 0.5
+ anchors.right: parent.right
+
+ onClicked: {
+ console.log("Address copied to clipboard");
+ clipboard.setText(address);
+ appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3);
+ }
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ color: MoneroComponents.Style.grey
+ Layout.fillWidth: true
+ height: 1
+ }
+
+ MoneroComponents.CheckBox {
+ id: addNewEntryCheckbox
+ border: false
+ checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
+ uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
+ fontSize: 16 * scaleRatio
+ iconOnTheLeft: true
+ Layout.fillWidth: true
+ Layout.topMargin: 10 * scaleRatio
+ text: qsTr("Add address") + translationManager.emptyString;
+ onClicked: {
+ root.showAddAddress();
+ }
+ }
+
+ }
+ ColumnLayout {
+ id: addContactLayout
+ visible: false
+ spacing: 0
+
+ MoneroComponents.Label {
+ fontSize: 32 * scaleRatio
+ wrapMode: Text.WordWrap
+ text: (root.editEntry ? qsTr("Edit an address") : qsTr("Add an address")) + translationManager.emptyString
+ }
+
+ MoneroComponents.LineEditMulti {
+ id: addressLine
+ Layout.topMargin: 20
+ labelText: qsTr("\
+ Address") + translationManager.emptyString
+ placeholderText: {
+ if(persistentSettings.nettype == NetworkType.MAINNET){
+ return "4.. / 8.. / OpenAlias";
+ } else if (persistentSettings.nettype == NetworkType.STAGENET){
+ return "5.. / 7..";
+ } else if(persistentSettings.nettype == NetworkType.TESTNET){
+ return "9.. / B..";
+ }
+ }
+ wrapMode: Text.WrapAnywhere
+ addressValidation: true
+ pasteButton: true
+ onPaste: function(clipboardText) {
+ const parsed = walletManager.parse_uri_to_object(clipboardText);
+ if (!parsed.error) {
+ addressLine.text = parsed.address;
+ descriptionLine.text = parsed.tx_description;
} else {
- clearFields();
+ addressLine.text = clipboardText;
+ }
+ }
+ inlineButton.icon: "../images/qr.png"
+ inlineButton.buttonColor: MoneroComponents.Style.orange
+ inlineButton.onClicked: {
+ cameraUi.state = "Capture"
+ cameraUi.qrcode_decoded.connect(root.updateFromQrCode)
+ }
+ inlineButtonVisible : appWindow.qrScannerEnabled && !addressLine.text
+ }
+
+ MoneroComponents.StandardButton {
+ id: resolveButton
+ Layout.topMargin: 10
+ text: qsTr("Resolve") + translationManager.emptyString
+ visible: TxUtils.isValidOpenAliasAddress(addressLine.text)
+ enabled : visible
+ 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.nettype)
+ if (parts[0] === "true") {
+ if (address_ok) {
+ // prepend openalias to description
+ descriptionLine.text = descriptionLine.text ? addressLine.text + " " + descriptionLine.text : addressLine.text
+ addressLine.text = parts[1]
+ } else {
+ root.oa_message(qsTr("No valid address found at this OpenAlias address"))
+ }
+ } else if (parts[0] === "false") {
+ if (address_ok) {
+ addressLine.text = parts[1]
+ root.oa_message(qsTr("Address found, but the DNSSEC signatures could not be verified, so this address may be spoofed"))
+ } else {
+ root.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 {
+ root.oa_message(qsTr("Internal error"))
+ }
+ } else {
+ root.oa_message(qsTr("Internal error"))
+ }
+ } else {
+ root.oa_message(qsTr("No address found"))
+ }
+ }
+ }
+
+ MoneroComponents.LineEditMulti {
+ id: descriptionLine
+ Layout.topMargin: 20
+ labelText: qsTr("\
+ Description") + translationManager.emptyString
+ placeholderText: qsTr("Add a name...") + translationManager.emptyString
+ }
+ RowLayout {
+ Layout.topMargin: 20
+ MoneroComponents.StandardButton {
+ id: addButton
+ text: (root.editEntry ? qsTr("Save") : qsTr("Add")) + translationManager.emptyString
+ enabled: root.checkInformation(addressLine.text, appWindow.persistentSettings.nettype)
+ onClicked: {
+ console.log("Add")
+ if (!currentWallet.addressBook.addRow(addressLine.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 {
+ if (root.editEntry) {
+ currentWallet.addressBook.deleteRow(addressBookListView.currentIndex);
+ }
+ root.showAddressBook();
+ }
+ }
+ }
+
+ Text {
+ id: cancelButton
+ Layout.leftMargin: 20
+ font.pixelSize: 16 * scaleRatio
+ font.bold: false
+ color: MoneroComponents.Style.defaultFontColor
+ text: qsTr("Cancel")
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: root.showAddressBook();
+ }
+ }
+
+ Text {
+ id: deleteButton
+ visible: root.editEntry
+ Layout.leftMargin: 20
+ font.pixelSize: 16 * scaleRatio
+ font.bold: false
+ color: MoneroComponents.Style.defaultFontColor
+ text: qsTr("Delete")
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ currentWallet.addressBook.deleteRow(addressBookListView.currentIndex);
+ root.showAddressBook();
+ }
}
}
}
}
}
- Rectangle {
- id: tableRect
- Layout.leftMargin: (isMobile ? 17 : 40) * scaleRatio
- Layout.rightMargin: (isMobile ? 17 : 40) * scaleRatio
- Layout.topMargin: (root.selectAndSend ? 40 : 0) * scaleRatio
- Layout.fillHeight: true
- Layout.fillWidth: true
- color: "transparent"
-
- Behavior on height {
- NumberAnimation { duration: 200; easing.type: Easing.InQuad }
- }
-
- MoneroComponents.Scroll {
- id: flickableScroll
- anchors.right: table.right
- anchors.rightMargin: -14 * scaleRatio
- anchors.top: table.top
- anchors.bottom: table.bottom
- flickable: table
- }
-
- MoneroComponents.AddressBookTable {
- id: table
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- onContentYChanged: flickableScroll.flickableContentYChanged()
- model: root.model
- selectAndSend: root.selectAndSend
- }
+ function checkInformation(address, nettype) {
+ address = address.trim()
+ var address_ok = walletManager.addressValid(address, nettype)
+ addressLine.error = !address_ok
+ return address_ok
}
- function checkInformation(address, payment_id, nettype) {
- address = address.trim()
- payment_id = payment_id.trim()
-
- var address_ok = walletManager.addressValid(address, nettype)
- var payment_id_ok = payment_id.length === 0 || walletManager.paymentIdValid(payment_id)
- var ipid = walletManager.paymentIdFromAddress(address, nettype)
- if (ipid.length > 0 && payment_id.length > 0)
- payment_id_ok = false
-
- addressLine.error = !address_ok
- paymentIdLine.error = !payment_id_ok
-
- return address_ok && payment_id_ok
+ function clearFields() {
+ addressLine.text = "";
+ descriptionLine.text = "";
}
- function onPageClosed() {
- root.selectAndSend = false;
+ function showAddressBook() {
+ addressBookEmptyLayout.visible = addressBookListView.count == 0
+ addressBookLayout.visible = addressBookListView.count >= 1;
+ addContactLayout.visible = false;
+ clearFields();
}
- function onPageCompleted() {
- console.log("adress book");
- root.model = currentWallet.addressBookModel;
+ function showAddAddress() {
+ root.editEntry = false;
+ addressBookEmptyLayout.visible = false
+ addressBookLayout.visible = false;
+ addContactLayout.visible = true;
+ }
+
+ function showEditAddress(address, description) {
+ //TODO: real contact editing, requires API change
+ root.editEntry = true;
+ addressBookEmptyLayout.visible = false
+ addressBookLayout.visible = false;
+ addContactLayout.visible = true;
+ addressLine.text = address;
+ descriptionLine.text = description;
}
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
console.log("updateFromQrCode")
addressLine.text = address
- paymentIdLine.text = payment_id
descriptionLine.text = recipient_name + " " + tx_description
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
}
- function setDescription(value) {
- descriptionLine.text = value;
- }
-
- function setPaymentId(value) {
- paymentIdLine.text = value;
- }
-
- function clearFields() {
- addressLine.text = "";
- paymentIdLine.text = "";
- descriptionLine.text = "";
- }
-
function oa_message(text) {
oaPopup.title = qsTr("OpenAlias error") + translationManager.emptyString
oaPopup.text = text
@@ -273,10 +485,21 @@ ColumnLayout {
property var onCloseCallback
id: oaPopup
cancelVisible: false
- onAccepted: {
+ onAccepted: {
if (onCloseCallback) {
onCloseCallback()
}
}
}
+ function onPageCompleted() {
+ console.log("adress book");
+ addressBookListView.model = currentWallet.addressBookModel;
+ showAddressBook();
+ }
+
+ function onPageClosed() {
+ root.selectAndSend = false;
+ root.editEntry = false;
+ clearFields();
+ }
}
diff --git a/qml.qrc b/qml.qrc
index 6f5088cb..acefb890 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -37,7 +37,6 @@
components/TipItem.qml
images/tip.png
components/Scroll.qml
- components/AddressBookTable.qml
images/moneroIcon.png
components/StandardDropdown.qml
images/whiteDropIndicator.png
@@ -53,7 +52,6 @@
images/expandRightPanel.png
images/dropdownCopy.png
images/dropdownCopy@2x.png
- images/dropdownDel.png
components/HistoryTable.qml
components/HistoryTableMobile.qml
images/moneroLogo2.png
@@ -158,6 +156,10 @@
fonts/Roboto-Regular.ttf
fonts/Roboto-Light.ttf
fonts/Roboto-Bold.ttf
+ fonts/RobotoMono-Medium.ttf
+ fonts/RobotoMono-Regular.ttf
+ fonts/RobotoMono-Light.ttf
+ fonts/RobotoMono-Bold.ttf
components/Style.qml
components/qmldir
components/InlineButton.qml
@@ -275,5 +277,11 @@
images/local-node-full@2x.png
wizard/WizardNavProgressDot.qml
wizard/WizardOpenWallet1.qml
+ images/arrow-right-in-circle.png
+ images/arrow-right-in-circle@2x.png
+ images/rename.png
+ images/rename@2x.png
+ images/clipboard.png
+ images/clipboard@2x.png