monero-gui/pages/Receive.qml

374 lines
16 KiB
QML
Raw Normal View History

2018-01-07 05:20:45 +00:00
// Copyright (c) 2014-2018, The Monero Project
2016-10-04 10:15:29 +00:00
//
// All rights reserved.
2016-10-04 10:15:29 +00:00
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
2016-10-04 10:15:29 +00:00
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
2016-10-04 10:15:29 +00:00
//
// 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.
2016-10-04 10:15:29 +00:00
//
// 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.
2016-10-04 10:15:29 +00:00
//
// 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.
2019-04-11 01:17:29 +00:00
import QtQuick 2.9
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
2019-06-17 15:14:13 +00:00
import FontAwesome 1.0
2018-12-08 15:55:29 +00:00
import "../components" as MoneroComponents
2019-04-11 01:17:29 +00:00
import "../components/effects/" as MoneroEffects
import moneroComponents.Clipboard 1.0
import moneroComponents.Wallet 1.0
import moneroComponents.WalletManager 1.0
import moneroComponents.TransactionHistory 1.0
import moneroComponents.TransactionHistoryModel 1.0
import moneroComponents.Subaddress 1.0
import moneroComponents.SubaddressModel 1.0
import "../js/TxUtils.js" as TxUtils
Rectangle {
id: pageReceive
2017-12-08 23:01:10 +00:00
color: "transparent"
property var model
property alias receiveHeight: mainLayout.height
function renameSubaddressLabel(_index){
inputDialog.labelText = qsTr("Set the label of the selected address:") + translationManager.emptyString;
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddress.setLabel(appWindow.currentWallet.currentSubaddressAccount, _index, inputDialog.inputText);
}
inputDialog.onRejectedCallback = null;
2019-12-08 23:44:39 +00:00
inputDialog.open(appWindow.currentWallet.getSubaddressLabel(appWindow.currentWallet.currentSubaddressAccount, _index))
}
Clipboard { id: clipboard }
/* main layout */
ColumnLayout {
id: mainLayout
2019-09-05 22:11:12 +00:00
anchors.margins: 20
2019-04-25 19:09:23 +00:00
anchors.topMargin: 40
2017-04-03 16:51:55 +00:00
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
2019-04-25 19:09:23 +00:00
spacing: 20
2017-04-03 16:51:55 +00:00
ColumnLayout {
id: addressRow
spacing: 0
2018-12-08 15:55:29 +00:00
MoneroComponents.LabelSubheader {
Layout.fillWidth: true
2019-04-16 09:09:46 +00:00
fontSize: 24
textFormat: Text.RichText
text: qsTr("Addresses") + translationManager.emptyString
}
ColumnLayout {
id: subaddressListRow
2019-04-25 19:09:23 +00:00
property int subaddressListItemHeight: 50
Layout.topMargin: 6
Layout.fillWidth: true
Layout.minimumWidth: 240
Layout.preferredHeight: subaddressListItemHeight * subaddressListView.count
visible: subaddressListView.count >= 1
ListView {
id: subaddressListView
Layout.fillWidth: true
2019-07-21 19:51:47 +00:00
Layout.fillHeight: true
clip: true
boundsBehavior: ListView.StopAtBounds
2019-04-16 09:09:46 +00:00
interactive: false
delegate: Rectangle {
id: tableItem2
height: subaddressListRow.subaddressListItemHeight
2020-06-12 01:09:18 +00:00
width: parent ? parent.width : undefined
Layout.fillWidth: true
color: itemMouseArea.containsMouse || index === appWindow.current_subaddress_table_index ? MoneroComponents.Style.titleBarButtonHoverColor : "transparent"
Rectangle{
anchors.right: parent.right
anchors.left: parent.left
anchors.top: parent.top
height: 1
2019-04-11 01:17:29 +00:00
color: MoneroComponents.Style.appWindowBorderColor
visible: index !== 0
2019-04-11 01:17:29 +00:00
MoneroEffects.ColorTransition {
targetObj: parent
blackColor: MoneroComponents.Style._b_appWindowBorderColor
whiteColor: MoneroComponents.Style._w_appWindowBorderColor
}
}
Rectangle {
anchors.fill: parent
2018-12-19 23:06:23 +00:00
anchors.topMargin: 5
anchors.rightMargin: 90
color: "transparent"
2018-12-08 15:55:29 +00:00
MoneroComponents.Label {
id: idLabel
2019-04-11 01:17:29 +00:00
color: index === appWindow.current_subaddress_table_index ? MoneroComponents.Style.defaultFontColor : "#757575"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
2019-04-25 19:09:23 +00:00
anchors.leftMargin: 6
2019-04-16 09:09:46 +00:00
fontSize: 16
text: "#" + index
2019-04-11 01:17:29 +00:00
themeTransition: false
}
2018-12-08 15:55:29 +00:00
MoneroComponents.Label {
id: nameLabel
color: index === appWindow.current_subaddress_table_index ? MoneroComponents.Style.defaultFontColor : MoneroComponents.Style.dimmedFontColor
anchors.verticalCenter: parent.verticalCenter
anchors.left: idLabel.right
2019-04-25 19:09:23 +00:00
anchors.leftMargin: 6
2019-04-16 09:09:46 +00:00
fontSize: 16
text: label
elide: Text.ElideRight
textWidth: addressLabel.x - nameLabel.x - 1
2019-04-11 01:17:29 +00:00
themeTransition: false
}
2018-12-08 15:55:29 +00:00
MoneroComponents.Label {
id: addressLabel
2019-04-11 01:17:29 +00:00
color: MoneroComponents.Style.defaultFontColor
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.right
2019-04-16 09:09:46 +00:00
anchors.leftMargin: -addressLabel.width - 5
fontSize: 16
fontFamily: MoneroComponents.Style.fontMonoRegular.name;
text: TxUtils.addressTruncatePretty(address, mainLayout.width < 520 ? 1 : (mainLayout.width < 650 ? 2 : 3))
2019-04-11 01:17:29 +00:00
themeTransition: false
}
MouseArea {
id: itemMouseArea
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
2019-04-11 01:17:29 +00:00
onClicked: subaddressListView.currentIndex = index;
}
}
2019-04-16 09:09:46 +00:00
RowLayout {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
2019-04-16 09:09:46 +00:00
anchors.rightMargin: 6
2019-04-11 01:17:29 +00:00
height: 21
2019-04-16 09:09:46 +00:00
spacing: 10
MoneroComponents.IconButton {
fontAwesomeFallbackIcon: FontAwesome.searchPlus
fontAwesomeFallbackSize: 22
color: MoneroComponents.Style.defaultFontColor
fontAwesomeFallbackOpacity: 0.5
Layout.preferredWidth: 23
Layout.preferredHeight: 21
onClicked: doSearchInHistory(address)
}
2019-04-16 09:09:46 +00:00
MoneroComponents.IconButton {
id: renameButton
image: "qrc:///images/edit.svg"
fontAwesomeFallbackIcon: FontAwesome.edit
fontAwesomeFallbackSize: 22
2019-04-16 09:09:46 +00:00
color: MoneroComponents.Style.defaultFontColor
opacity: 0.5
Layout.preferredWidth: 23
Layout.preferredHeight: 21
visible: index !== 0
tooltip: qsTr("Edit address label") + translationManager.emptyString
2019-04-16 09:09:46 +00:00
onClicked: {
renameSubaddressLabel(index);
}
}
2019-04-16 09:09:46 +00:00
MoneroComponents.IconButton {
id: copyButton
image: "qrc:///images/copy.svg"
fontAwesomeFallbackIcon: FontAwesome.clipboard
fontAwesomeFallbackSize: 22
2019-04-16 09:09:46 +00:00
color: MoneroComponents.Style.defaultFontColor
opacity: 0.5
Layout.preferredWidth: 16
Layout.preferredHeight: 21
tooltip: qsTr("Copy address to clipboard") + translationManager.emptyString
2019-04-16 09:09:46 +00:00
onClicked: {
console.log("Address copied to clipboard");
clipboard.setText(address);
appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3);
}
}
}
}
onCurrentItemChanged: {
// reset global vars
2018-12-08 15:55:29 +00:00
appWindow.current_subaddress_table_index = subaddressListView.currentIndex;
appWindow.current_address = appWindow.currentWallet.address(
appWindow.currentWallet.currentSubaddressAccount,
subaddressListView.currentIndex
);
}
}
}
Rectangle {
2019-04-11 01:17:29 +00:00
color: MoneroComponents.Style.appWindowBorderColor
Layout.fillWidth: true
height: 1
2019-04-11 01:17:29 +00:00
MoneroEffects.ColorTransition {
targetObj: parent
blackColor: MoneroComponents.Style._b_appWindowBorderColor
whiteColor: MoneroComponents.Style._w_appWindowBorderColor
}
}
MoneroComponents.CheckBox {
id: addNewAddressCheckbox
border: false
uncheckedIcon: FontAwesome.plusCircle
toggleOnClick: false
fontAwesomeIcons: true
2019-04-16 09:09:46 +00:00
fontSize: 16
iconOnTheLeft: true
Layout.fillWidth: true
2019-04-25 19:09:23 +00:00
Layout.topMargin: 10
text: qsTr("Create new address") + translationManager.emptyString;
onClicked: {
inputDialog.labelText = qsTr("Set the label of the new address:") + translationManager.emptyString
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddress.addRow(appWindow.currentWallet.currentSubaddressAccount, inputDialog.inputText)
current_subaddress_table_index = appWindow.currentWallet.numSubaddresses(appWindow.currentWallet.currentSubaddressAccount) - 1
subaddressListView.currentIndex = current_subaddress_table_index
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
}
}
}
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
2019-04-25 19:09:23 +00:00
spacing: 11
property int qrSize: 220
Rectangle {
id: qrContainer
2019-04-11 01:17:29 +00:00
color: MoneroComponents.Style.blackTheme ? "white" : "transparent"
Layout.fillWidth: true
Layout.maximumWidth: parent.qrSize
Layout.preferredHeight: width
2019-04-25 19:09:23 +00:00
radius: 4
2018-10-27 12:42:25 +00:00
Image {
id: qrCode
anchors.fill: parent
2019-04-25 19:09:23 +00:00
anchors.margins: 1
2018-04-27 17:49:45 +00:00
smooth: false
fillMode: Image.PreserveAspectFit
source: "image://qrcode/" + TxUtils.makeQRCodeString(appWindow.current_address)
MouseArea {
2018-04-27 17:49:45 +00:00
anchors.fill: parent
acceptedButtons: Qt.RightButton
onPressAndHold: qrFileDialog.open()
}
}
}
MoneroComponents.StandardButton {
Layout.preferredWidth: 220
small: true
text: FontAwesome.save + " %1".arg(qsTr("Save as image")) + translationManager.emptyString
label.font.family: FontAwesome.fontFamily
fontSize: 13
onClicked: qrFileDialog.open()
}
MoneroComponents.StandardButton {
Layout.preferredWidth: 220
small: true
text: FontAwesome.eye + " %1".arg(qsTr("Show on device")) + translationManager.emptyString
label.font.family: FontAwesome.fontFamily
fontSize: 13
visible: appWindow.currentWallet ? appWindow.currentWallet.isHwBacked() : false
onClicked: {
appWindow.currentWallet.deviceShowAddressAsync(
appWindow.currentWallet.currentSubaddressAccount,
appWindow.current_subaddress_table_index,
'');
2019-06-17 15:14:13 +00:00
}
}
}
MessageDialog {
id: receivePageDialog
standardButtons: StandardButton.Ok
}
2017-01-23 04:15:49 +00:00
FileDialog {
id: qrFileDialog
title: qsTr("Please choose a name") + translationManager.emptyString
2017-01-23 04:15:49 +00:00
folder: shortcuts.pictures
selectExisting: false
nameFilters: ["Image (*.png)"]
2017-01-23 04:15:49 +00:00
onAccepted: {
2018-12-08 15:55:29 +00:00
if(!walletManager.saveQrCode(TxUtils.makeQRCodeString(appWindow.current_address), walletManager.urlToLocalPath(fileUrl))) {
2017-01-23 04:15:49 +00:00
console.log("Failed to save QrCode to file " + walletManager.urlToLocalPath(fileUrl) )
receivePageDialog.title = qsTr("Save QrCode") + translationManager.emptyString;
receivePageDialog.text = qsTr("Failed to save QrCode to ") + walletManager.urlToLocalPath(fileUrl) + translationManager.emptyString;
receivePageDialog.icon = StandardIcon.Error
receivePageDialog.open()
2017-01-23 04:15:49 +00:00
}
}
}
}
2016-10-04 10:15:29 +00:00
function onPageCompleted() {
console.log("Receive page loaded");
subaddressListView.model = appWindow.currentWallet.subaddressModel;
2016-10-04 10:15:29 +00:00
if (appWindow.currentWallet) {
2018-12-08 15:55:29 +00:00
appWindow.current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, 0)
appWindow.currentWallet.subaddress.refresh(appWindow.currentWallet.currentSubaddressAccount)
2016-10-04 10:15:29 +00:00
}
}
2018-12-18 19:06:29 +00:00
function clearFields() {
2019-01-14 00:02:44 +00:00
// @TODO: add fields
2018-12-18 19:06:29 +00:00
}
function onPageClosed() {
}
}