mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-11-16 15:58:11 +00:00
Receive: implement payment request
This commit is contained in:
parent
51828babbb
commit
946fa538b9
6 changed files with 334 additions and 7 deletions
|
@ -74,13 +74,29 @@ function isValidOpenAliasAddress(address) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeQRCodeString(addr, amount) {
|
function makeQRCodeString(addr, amount, txDescription, recipientName) {
|
||||||
var XMR_URI_SCHEME = "monero:"
|
var XMR_URI_SCHEME = "monero:"
|
||||||
var XMR_AMOUNT = "tx_amount"
|
var XMR_AMOUNT = "tx_amount"
|
||||||
|
var XMR_RECIPIENT_NAME = "recipient_name"
|
||||||
|
var XMR_TX_DESCRIPTION = "tx_description"
|
||||||
var qrCodeString =""
|
var qrCodeString =""
|
||||||
qrCodeString += (XMR_URI_SCHEME + addr)
|
qrCodeString += (XMR_URI_SCHEME + addr)
|
||||||
if (amount !== undefined && amount !== ""){
|
if (amount !== undefined && amount !== ""){
|
||||||
qrCodeString += ("?" + XMR_AMOUNT + "=" + amount)
|
qrCodeString += ("?" + XMR_AMOUNT + "=" + amount)
|
||||||
}
|
}
|
||||||
|
if (txDescription !== undefined && txDescription !== ""){
|
||||||
|
if (amount == ""){
|
||||||
|
qrCodeString += ("?" + XMR_TX_DESCRIPTION + "=" + encodeURI(txDescription))
|
||||||
|
} else {
|
||||||
|
qrCodeString += ("&" + XMR_TX_DESCRIPTION + "=" + encodeURI(txDescription))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (recipientName !== undefined && recipientName !== ""){
|
||||||
|
if (amount == "" && txDescription == ""){
|
||||||
|
qrCodeString += ("?" + XMR_RECIPIENT_NAME + "=" + encodeURI(recipientName))
|
||||||
|
} else {
|
||||||
|
qrCodeString += ("&" + XMR_RECIPIENT_NAME + "=" + encodeURI(recipientName))
|
||||||
|
}
|
||||||
|
}
|
||||||
return qrCodeString
|
return qrCodeString
|
||||||
}
|
}
|
||||||
|
|
9
main.qml
9
main.qml
|
@ -1251,6 +1251,15 @@ ApplicationWindow {
|
||||||
return (amount * ticker).toFixed(2);
|
return (amount * ticker).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fiatApiConvertToXMR(amount) {
|
||||||
|
const ticker = appWindow.fiatPrice;
|
||||||
|
if(ticker <= 0){
|
||||||
|
fiatApiError("Invalid ticker value: " + ticker);
|
||||||
|
return "?.??";
|
||||||
|
}
|
||||||
|
return (amount / ticker).toFixed(12);
|
||||||
|
}
|
||||||
|
|
||||||
function fiatApiUpdateBalance(balance){
|
function fiatApiUpdateBalance(balance){
|
||||||
// update balance card
|
// update balance card
|
||||||
var bFiat = "?.??"
|
var bFiat = "?.??"
|
||||||
|
|
|
@ -50,6 +50,7 @@ Rectangle {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
property var model
|
property var model
|
||||||
property alias receiveHeight: mainLayout.height
|
property alias receiveHeight: mainLayout.height
|
||||||
|
property var state: "Address"
|
||||||
|
|
||||||
function renameSubaddressLabel(_index){
|
function renameSubaddressLabel(_index){
|
||||||
inputDialog.labelText = qsTr("Set the label of the selected address:") + translationManager.emptyString;
|
inputDialog.labelText = qsTr("Set the label of the selected address:") + translationManager.emptyString;
|
||||||
|
@ -60,6 +61,17 @@ Rectangle {
|
||||||
inputDialog.open(appWindow.currentWallet.getSubaddressLabel(appWindow.currentWallet.currentSubaddressAccount, _index))
|
inputDialog.open(appWindow.currentWallet.getSubaddressLabel(appWindow.currentWallet.currentSubaddressAccount, _index))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateQRCodeString() {
|
||||||
|
if (pageReceive.state == "PaymentRequest") {
|
||||||
|
return TxUtils.makeQRCodeString(appWindow.current_address,
|
||||||
|
(amountToReceiveXMR.text != "" && parseFloat(amountToReceiveXMR.text) != 0 ? amountToReceiveXMR.text : ""),
|
||||||
|
(txDescriptionInput.text != "" ? txDescriptionInput.text : ""),
|
||||||
|
(receiverNameInput.text != "" ? receiverNameInput.text : ""));
|
||||||
|
} else {
|
||||||
|
return TxUtils.makeQRCodeString(appWindow.current_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Clipboard { id: clipboard }
|
Clipboard { id: clipboard }
|
||||||
|
|
||||||
/* main layout */
|
/* main layout */
|
||||||
|
@ -80,6 +92,26 @@ Rectangle {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
property int qrSize: 220
|
property int qrSize: 220
|
||||||
|
|
||||||
|
MoneroComponents.Navbar {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.bottomMargin: 10
|
||||||
|
|
||||||
|
MoneroComponents.NavbarItem {
|
||||||
|
active: state == "Address"
|
||||||
|
text: qsTr("Address") + translationManager.emptyString
|
||||||
|
onSelected: state = "Address"
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.NavbarItem {
|
||||||
|
active: state == "PaymentRequest"
|
||||||
|
text: qsTr("Payment request") + translationManager.emptyString
|
||||||
|
onSelected: {
|
||||||
|
state = "PaymentRequest";
|
||||||
|
qrCodeTextMouseArea.hoverEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: qrContainer
|
id: qrContainer
|
||||||
color: MoneroComponents.Style.blackTheme ? "white" : "transparent"
|
color: MoneroComponents.Style.blackTheme ? "white" : "transparent"
|
||||||
|
@ -95,16 +127,19 @@ Rectangle {
|
||||||
anchors.margins: 1
|
anchors.margins: 1
|
||||||
smooth: false
|
smooth: false
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: "image://qrcode/" + TxUtils.makeQRCodeString(appWindow.current_address)
|
source: "image://qrcode/" + generateQRCodeString();
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
onEntered: qrCodeTooltip.tooltipPopup.open()
|
||||||
|
onExited: qrCodeTooltip.tooltipPopup.close()
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (mouse.button == Qt.LeftButton){
|
if (mouse.button == Qt.LeftButton){
|
||||||
selectedAddressDetailsColumn.qrSize = selectedAddressDetailsColumn.qrSize == 220 ? 300 : 220;
|
walletManager.saveQrCodeToClipboard(generateQRCodeString());
|
||||||
|
appWindow.showStatusMessage(qsTr("QR code copied to clipboard") + translationManager.emptyString, 3);
|
||||||
} else if (mouse.button == Qt.RightButton){
|
} else if (mouse.button == Qt.RightButton){
|
||||||
qrMenu.x = this.mouseX;
|
qrMenu.x = this.mouseX;
|
||||||
qrMenu.y = this.mouseY;
|
qrMenu.y = this.mouseY;
|
||||||
|
@ -118,11 +153,258 @@ Rectangle {
|
||||||
id: qrMenu
|
id: qrMenu
|
||||||
title: "QrCode"
|
title: "QrCode"
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Copy to clipboard") + translationManager.emptyString;
|
||||||
|
onTriggered: walletManager.saveQrCodeToClipboard(generateQRCodeString())
|
||||||
|
}
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("Save as Image") + translationManager.emptyString;
|
text: qsTr("Save as Image") + translationManager.emptyString;
|
||||||
onTriggered: qrFileDialog.open()
|
onTriggered: qrFileDialog.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Tooltip {
|
||||||
|
id: qrCodeTooltip
|
||||||
|
text: qsTr("Left click: copy QR code to clipboard") + "<br>" + qsTr("Right click: save QR code as image file") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: qrCodeText
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: 6
|
||||||
|
Layout.maximumWidth: 285
|
||||||
|
Layout.minimumHeight: 75
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
visible: paymentRequestGridLayout.visible
|
||||||
|
font.pixelSize: 12
|
||||||
|
color: qrCodeTextMouseArea.containsMouse ? MoneroComponents.Style.orange : MoneroComponents.Style.defaultFontColor
|
||||||
|
text: generateQRCodeString();
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
tooltip: qsTr("Copy payment request to clipboard") + translationManager.emptyString
|
||||||
|
themeTransition: false
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: qrCodeTextMouseArea
|
||||||
|
hoverEnabled: false //true when Payment request navbar button is clicked (fix bug displaying tooltip when navbar button is clicked)
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onEntered: parent.tooltipPopup.open()
|
||||||
|
onExited: parent.tooltipPopup.close()
|
||||||
|
onClicked: {
|
||||||
|
clipboard.setText(qrCodeText.text);
|
||||||
|
appWindow.showStatusMessage(qsTr("Payment request copied to clipboard") + translationManager.emptyString, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: paymentRequestGridLayout
|
||||||
|
columns: 3
|
||||||
|
rows: 4
|
||||||
|
visible: pageReceive.state == "PaymentRequest"
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: 6
|
||||||
|
Layout.preferredWidth: 285
|
||||||
|
Layout.maximumWidth: 285
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
id: amountTitleFiat
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
Layout.preferredWidth: 90
|
||||||
|
visible: persistentSettings.fiatPriceEnabled
|
||||||
|
fontSize: 14
|
||||||
|
text: qsTr("Amount") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Input {
|
||||||
|
id: amountToReceiveFiat
|
||||||
|
Layout.preferredWidth: 165
|
||||||
|
Layout.maximumWidth: 165
|
||||||
|
visible: persistentSettings.fiatPriceEnabled
|
||||||
|
topPadding: 5
|
||||||
|
leftPadding: 5
|
||||||
|
font.family: MoneroComponents.Style.fontMonoRegular.name
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.bold: false
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
selectByMouse: true
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
placeholderText: "0.00"
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "transparent" : "white"
|
||||||
|
radius: 3
|
||||||
|
border.color: parent.activeFocus ? MoneroComponents.Style.inputBorderColorActive : MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
onTextEdited: {
|
||||||
|
text = text.trim().replace(",", ".");
|
||||||
|
const match = text.match(/^0+(\d.*)/);
|
||||||
|
if (match) {
|
||||||
|
const cursorPosition = cursorPosition;
|
||||||
|
text = match[1];
|
||||||
|
cursorPosition = Math.max(cursorPosition, 1) - 1;
|
||||||
|
} else if(text.indexOf('.') === 0){
|
||||||
|
text = '0' + text;
|
||||||
|
if (text.length > 2) {
|
||||||
|
cursorPosition = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (amountToReceiveFiat.text == "") {
|
||||||
|
amountToReceiveXMR.text = "";
|
||||||
|
} else {
|
||||||
|
amountToReceiveXMR.text = fiatApiConvertToXMR(amountToReceiveFiat.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validator: RegExpValidator {
|
||||||
|
regExp: /^\s*(\d{1,8})?([\.,]\d{1,2})?\s*$/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
visible: persistentSettings.fiatPriceEnabled
|
||||||
|
fontSize: 14
|
||||||
|
text: appWindow.fiatApiCurrencySymbol();
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
id: amountTitleXMR
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
Layout.preferredWidth: 90
|
||||||
|
fontSize: 14
|
||||||
|
text: persistentSettings.fiatPriceEnabled ? "" : qsTr("Amount") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Input {
|
||||||
|
id: amountToReceiveXMR
|
||||||
|
Layout.preferredWidth: 165
|
||||||
|
Layout.maximumWidth: 165
|
||||||
|
topPadding: 5
|
||||||
|
leftPadding: 5
|
||||||
|
font.family: MoneroComponents.Style.fontMonoRegular.name
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.bold: false
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
selectByMouse: true
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
placeholderText: "0.000000000000"
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "transparent" : "white"
|
||||||
|
radius: 3
|
||||||
|
border.color: parent.activeFocus ? MoneroComponents.Style.inputBorderColorActive : MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
onTextEdited: {
|
||||||
|
text = text.trim().replace(",", ".");
|
||||||
|
const match = text.match(/^0+(\d.*)/);
|
||||||
|
if (match) {
|
||||||
|
const cursorPosition = cursorPosition;
|
||||||
|
text = match[1];
|
||||||
|
cursorPosition = Math.max(cursorPosition, 1) - 1;
|
||||||
|
} else if(text.indexOf('.') === 0){
|
||||||
|
text = '0' + text;
|
||||||
|
if (text.length > 2) {
|
||||||
|
cursorPosition = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (amountToReceiveXMR.text == "") {
|
||||||
|
amountToReceiveFiat.text = "";
|
||||||
|
} else {
|
||||||
|
amountToReceiveFiat.text = fiatApiConvertToFiat(amountToReceiveXMR.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validator: RegExpValidator {
|
||||||
|
regExp: /^\s*(\d{1,8})?([\.,]\d{1,12})?\s*$/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
fontSize: 14
|
||||||
|
text: "XMR"
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
id: txDescription
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
Layout.preferredWidth: 90
|
||||||
|
fontSize: 14
|
||||||
|
text: qsTr("Description") + translationManager.emptyString
|
||||||
|
tooltip: qsTr("What is being payed for (a product, service, donation) (optional)") + translationManager.emptyString
|
||||||
|
tooltipIconVisible: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Input {
|
||||||
|
id: txDescriptionInput
|
||||||
|
Layout.preferredWidth: 165
|
||||||
|
Layout.maximumWidth: 165
|
||||||
|
topPadding: 7
|
||||||
|
leftPadding: 7
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.bold: false
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
selectByMouse: true
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
placeholderText: qsTr("Visible to the sender") + translationManager.emptyString
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "transparent" : "white"
|
||||||
|
radius: 3
|
||||||
|
border.color: parent.activeFocus ? MoneroComponents.Style.inputBorderColorActive : MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
fontSize: 14
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
id: receiverNameLabel
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
Layout.preferredWidth: 90
|
||||||
|
fontSize: 14
|
||||||
|
text: qsTr("Your name") + translationManager.emptyString
|
||||||
|
tooltip: qsTr("Your name, company or website (optional)") + translationManager.emptyString
|
||||||
|
tooltipIconVisible: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Input {
|
||||||
|
id: receiverNameInput
|
||||||
|
Layout.preferredWidth: 165
|
||||||
|
Layout.maximumWidth: 165
|
||||||
|
topPadding: 7
|
||||||
|
leftPadding: 7
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.bold: false
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
selectByMouse: true
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
placeholderText: qsTr("Visible to the sender") + translationManager.emptyString
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "transparent" : "white"
|
||||||
|
radius: 3
|
||||||
|
border.color: parent.activeFocus ? MoneroComponents.Style.inputBorderColorActive : MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
fontSize: 14
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
|
@ -131,6 +413,7 @@ Rectangle {
|
||||||
Layout.preferredWidth: 220
|
Layout.preferredWidth: 220
|
||||||
Layout.maximumWidth: 220
|
Layout.maximumWidth: 220
|
||||||
Layout.topMargin: 15
|
Layout.topMargin: 15
|
||||||
|
visible: pageReceive.state == "Address"
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
text: qsTr("Address #") + subaddressListView.currentIndex + translationManager.emptyString
|
text: qsTr("Address #") + subaddressListView.currentIndex + translationManager.emptyString
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
|
@ -147,6 +430,7 @@ Rectangle {
|
||||||
Layout.preferredWidth: 220
|
Layout.preferredWidth: 220
|
||||||
Layout.maximumWidth: 220
|
Layout.maximumWidth: 220
|
||||||
Layout.topMargin: 10
|
Layout.topMargin: 10
|
||||||
|
visible: pageReceive.state == "Address"
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
text: "(" + qsTr("no label") + ")" + translationManager.emptyString
|
text: "(" + qsTr("no label") + ")" + translationManager.emptyString
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
|
@ -175,6 +459,7 @@ Rectangle {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.maximumWidth: 300
|
Layout.maximumWidth: 300
|
||||||
Layout.topMargin: 11
|
Layout.topMargin: 11
|
||||||
|
visible: pageReceive.state == "Address"
|
||||||
text: appWindow.current_address ? appWindow.current_address : ""
|
text: appWindow.current_address ? appWindow.current_address : ""
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
@ -464,12 +749,14 @@ Rectangle {
|
||||||
selectExisting: false
|
selectExisting: false
|
||||||
nameFilters: ["Image (*.png)"]
|
nameFilters: ["Image (*.png)"]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
if(!walletManager.saveQrCode(TxUtils.makeQRCodeString(appWindow.current_address), walletManager.urlToLocalPath(fileUrl))) {
|
if(!walletManager.saveQrCode(generateQRCodeString(), walletManager.urlToLocalPath(fileUrl))) {
|
||||||
console.log("Failed to save QrCode to file " + walletManager.urlToLocalPath(fileUrl) )
|
console.log("Failed to save QrCode to file " + walletManager.urlToLocalPath(fileUrl) )
|
||||||
receivePageDialog.title = qsTr("Save QrCode") + translationManager.emptyString;
|
receivePageDialog.title = qsTr("Save QrCode") + translationManager.emptyString;
|
||||||
receivePageDialog.text = qsTr("Failed to save QrCode to ") + walletManager.urlToLocalPath(fileUrl) + translationManager.emptyString;
|
receivePageDialog.text = qsTr("Failed to save QrCode to ") + walletManager.urlToLocalPath(fileUrl) + translationManager.emptyString;
|
||||||
receivePageDialog.icon = StandardIcon.Error
|
receivePageDialog.icon = StandardIcon.Error
|
||||||
receivePageDialog.open()
|
receivePageDialog.open()
|
||||||
|
} else {
|
||||||
|
appWindow.showStatusMessage(qsTr("QR code saved to ") + walletManager.urlToLocalPath(fileUrl) + translationManager.emptyString, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,6 +764,7 @@ Rectangle {
|
||||||
|
|
||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
console.log("Receive page loaded");
|
console.log("Receive page loaded");
|
||||||
|
pageReceive.clearFields();
|
||||||
subaddressListView.model = appWindow.currentWallet.subaddressModel;
|
subaddressListView.model = appWindow.currentWallet.subaddressModel;
|
||||||
|
|
||||||
if (appWindow.currentWallet) {
|
if (appWindow.currentWallet) {
|
||||||
|
@ -489,7 +777,10 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearFields() {
|
function clearFields() {
|
||||||
// @TODO: add fields
|
amountToReceiveFiat.text = "";
|
||||||
|
amountToReceiveXMR.text = "";
|
||||||
|
txDescriptionInput.text = "";
|
||||||
|
receiverNameInput.text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPageClosed() {
|
function onPageClosed() {
|
||||||
|
|
|
@ -102,7 +102,7 @@ Rectangle {
|
||||||
|
|
||||||
recipientModel.newRecipient(address, Utils.removeTrailingZeros(amount || ""));
|
recipientModel.newRecipient(address, Utils.removeTrailingZeros(amount || ""));
|
||||||
setPaymentId(payment_id || "");
|
setPaymentId(payment_id || "");
|
||||||
setDescription((recipient_name ? recipient_name + " " : "") + (tx_description || ""));
|
setDescription((recipient_name ? recipient_name + (tx_description ? " (" + tx_description + ")" : "") : (tx_description || "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
|
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
|
||||||
|
@ -404,7 +404,7 @@ Rectangle {
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
const parsed = walletManager.parse_uri_to_object(text);
|
const parsed = walletManager.parse_uri_to_object(text);
|
||||||
if (!parsed.error) {
|
if (!parsed.error) {
|
||||||
fillPaymentDetails(parsed.address, parsed.payment_id, parsed.amount, parsed.tx_description);
|
fillPaymentDetails(parsed.address, parsed.payment_id, parsed.amount, parsed.tx_description, parsed.recipient_name);
|
||||||
}
|
}
|
||||||
address = text;
|
address = text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "wallet/api/wallet2_api.h"
|
#include "wallet/api/wallet2_api.h"
|
||||||
#include "zxcvbn-c/zxcvbn.h"
|
#include "zxcvbn-c/zxcvbn.h"
|
||||||
#include "QRCodeImageProvider.h"
|
#include "QRCodeImageProvider.h"
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QGuiApplication>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
@ -480,6 +482,14 @@ bool WalletManager::saveQrCode(const QString &code, const QString &path) const
|
||||||
return QRCodeImageProvider::genQrImage(code, &size).scaled(size.expandedTo(QSize(240, 240)), Qt::KeepAspectRatio).save(path, "PNG", 100);
|
return QRCodeImageProvider::genQrImage(code, &size).scaled(size.expandedTo(QSize(240, 240)), Qt::KeepAspectRatio).save(path, "PNG", 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WalletManager::saveQrCodeToClipboard(const QString &code) const
|
||||||
|
{
|
||||||
|
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||||
|
QSize size;
|
||||||
|
clipboard->setImage(QRCodeImageProvider::genQrImage(code, &size).scaled(size.expandedTo(QSize(240, 240)), Qt::KeepAspectRatio), QClipboard::Clipboard);
|
||||||
|
clipboard->setImage(QRCodeImageProvider::genQrImage(code, &size).scaled(size.expandedTo(QSize(240, 240)), Qt::KeepAspectRatio), QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
void WalletManager::checkUpdatesAsync(
|
void WalletManager::checkUpdatesAsync(
|
||||||
const QString &software,
|
const QString &software,
|
||||||
const QString &subdir,
|
const QString &subdir,
|
||||||
|
|
|
@ -180,6 +180,7 @@ public:
|
||||||
Q_INVOKABLE bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error) const;
|
Q_INVOKABLE bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error) const;
|
||||||
Q_INVOKABLE QVariantMap parse_uri_to_object(const QString &uri) const;
|
Q_INVOKABLE QVariantMap parse_uri_to_object(const QString &uri) const;
|
||||||
Q_INVOKABLE bool saveQrCode(const QString &, const QString &) const;
|
Q_INVOKABLE bool saveQrCode(const QString &, const QString &) const;
|
||||||
|
Q_INVOKABLE void saveQrCodeToClipboard(const QString &) const;
|
||||||
Q_INVOKABLE void checkUpdatesAsync(
|
Q_INVOKABLE void checkUpdatesAsync(
|
||||||
const QString &software,
|
const QString &software,
|
||||||
const QString &subdir,
|
const QString &subdir,
|
||||||
|
|
Loading…
Reference in a new issue