mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-23 03:59:29 +00:00
PaymentRequestDialog
This commit is contained in:
parent
3767e736c2
commit
e512e539b6
11 changed files with 368 additions and 1 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "dialog/PaymentRequestDialog.h"
|
||||
#include "dialog/QrCodeDialog.h"
|
||||
#include "model/ModelUtils.h"
|
||||
#include "utils/Icons.h"
|
||||
|
@ -60,6 +61,8 @@ ReceiveWidget::ReceiveWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
|
|||
|
||||
connect(ui->check_showUsed, &QCheckBox::clicked, this, &ReceiveWidget::setShowUsedAddresses);
|
||||
connect(ui->check_showHidden, &QCheckBox::clicked, this, &ReceiveWidget::setShowHiddenAddresses);
|
||||
|
||||
connect(ui->btn_createPaymentRequest, &QPushButton::clicked, this, &ReceiveWidget::createPaymentRequest);
|
||||
}
|
||||
|
||||
void ReceiveWidget::setSearchbarVisible(bool visible) {
|
||||
|
@ -118,6 +121,18 @@ void ReceiveWidget::showContextMenu(const QPoint &point) {
|
|||
menu->popup(ui->addresses->viewport()->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void ReceiveWidget::createPaymentRequest() {
|
||||
QModelIndex index = ui->addresses->currentIndex();
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString address = index.model()->data(index.siblingAtColumn(SubaddressModel::Address), Qt::UserRole).toString();
|
||||
|
||||
PaymentRequestDialog dialog{this, m_ctx, address};
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void ReceiveWidget::onShowTransactions() {
|
||||
QModelIndex index = ui->addresses->currentIndex();
|
||||
if (!index.isValid()) {
|
||||
|
@ -190,6 +205,7 @@ void ReceiveWidget::updateQrCode(){
|
|||
QModelIndex index = ui->addresses->currentIndex();
|
||||
if (!index.isValid()) {
|
||||
ui->qrCode->clear();
|
||||
ui->btn_createPaymentRequest->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -199,6 +215,7 @@ void ReceiveWidget::updateQrCode(){
|
|||
int width = ui->qrCode->width() - 4;
|
||||
if (qrc.isValid()) {
|
||||
ui->qrCode->setPixmap(qrc.toPixmap(1).scaled(width, width, Qt::KeepAspectRatio));
|
||||
ui->btn_createPaymentRequest->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ public slots:
|
|||
void setShowHiddenAddresses(bool show);
|
||||
void setSearchFilter(const QString &filter);
|
||||
void onShowTransactions();
|
||||
void createPaymentRequest();
|
||||
|
||||
signals:
|
||||
void showTransactions(const QString& address);
|
||||
|
|
|
@ -69,6 +69,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_createPaymentRequest">
|
||||
<property name="text">
|
||||
<string>Payment Request</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
|
|
|
@ -26,7 +26,7 @@ SendWidget::SendWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
|
|||
QString amount_rx = R"(^\d{0,8}[\.,]\d{0,12}|(all)$)";
|
||||
QRegExp rx;
|
||||
rx.setPattern(amount_rx);
|
||||
QValidator *validator = new QRegExpValidator(rx, this);
|
||||
QValidator *validator = new QRegExpValidator(rx, this);
|
||||
ui->lineAmount->setValidator(validator);
|
||||
|
||||
connect(m_ctx.get(), &AppContext::initiateTransaction, this, &SendWidget::onInitiateTransaction);
|
||||
|
|
82
src/dialog/PaymentRequestDialog.cpp
Normal file
82
src/dialog/PaymentRequestDialog.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// Copyright (c) 2020-2021, The Monero Project.
|
||||
|
||||
#include "PaymentRequestDialog.h"
|
||||
#include "ui_PaymentRequestDialog.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QRegExpValidator>
|
||||
|
||||
#include "WalletManager.h"
|
||||
|
||||
PaymentRequestDialog::PaymentRequestDialog(QWidget *parent, QSharedPointer<AppContext> ctx, QString address)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::PaymentRequestDialog)
|
||||
, m_ctx(std::move(ctx))
|
||||
, m_address(std::move(address))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QString amount_rx = R"(^\d{0,8}[\.]\d{0,12}|(all)$)";
|
||||
QRegExp rx;
|
||||
rx.setPattern(amount_rx);
|
||||
QValidator *validator = new QRegExpValidator(rx, this);
|
||||
ui->line_amountXMR->setValidator(validator);
|
||||
|
||||
connect(ui->line_amountXMR, &QLineEdit::textChanged, this, &PaymentRequestDialog::updatePaymentRequest);
|
||||
connect(ui->line_description, &QLineEdit::textChanged, this, &PaymentRequestDialog::updatePaymentRequest);
|
||||
connect(ui->line_recipient, &QLineEdit::textChanged, this, &PaymentRequestDialog::updatePaymentRequest);
|
||||
|
||||
connect(ui->btn_copyLink, &QPushButton::clicked, this, &PaymentRequestDialog::copyLink);
|
||||
connect(ui->btn_copyImage, &QPushButton::clicked, this, &PaymentRequestDialog::copyImage);
|
||||
connect(ui->btn_saveImage, &QPushButton::clicked, this, &PaymentRequestDialog::saveImage);
|
||||
|
||||
this->updatePaymentRequest();
|
||||
|
||||
ui->line_amountXMR->setFocus();
|
||||
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
void PaymentRequestDialog::updatePaymentRequest() {
|
||||
QString description = ui->line_description->text();
|
||||
QString recipient = ui->line_recipient->text();
|
||||
quint64 amount = WalletManager::amountFromString(ui->line_amountXMR->text());
|
||||
|
||||
QString uri = m_ctx->wallet->make_uri(m_address, amount, description, recipient);
|
||||
|
||||
ui->line_paymentRequestUri->setText(uri);
|
||||
ui->line_paymentRequestUri->setCursorPosition(0);
|
||||
|
||||
// TODO: memory leak, cba to refactor now
|
||||
m_qrCode = new QrCode(uri, QrCode::Version::AUTO, QrCode::ErrorCorrectionLevel::MEDIUM);
|
||||
if (m_qrCode->isValid()) {
|
||||
ui->qrWidget->setQrCode(m_qrCode);
|
||||
}
|
||||
}
|
||||
|
||||
void PaymentRequestDialog::copyLink() {
|
||||
Utils::copyToClipboard(ui->line_paymentRequestUri->text());
|
||||
QMessageBox::information(this, "Information", "Payment request link copied to clipboard.");
|
||||
}
|
||||
|
||||
void PaymentRequestDialog::copyImage() {
|
||||
QApplication::clipboard()->setPixmap(m_qrCode->toPixmap(1).scaled(500, 500, Qt::KeepAspectRatio));
|
||||
QMessageBox::information(this, "Information", "QR code copied to clipboard.");
|
||||
}
|
||||
|
||||
void PaymentRequestDialog::saveImage() {
|
||||
QString filename = QFileDialog::getSaveFileName(this, "Select where to save file", QDir::current().filePath("qrcode.png"));
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
m_qrCode->toPixmap(1).scaled(500, 500, Qt::KeepAspectRatio).save(&file, "PNG");
|
||||
QMessageBox::information(this, "Information", "QR code saved to file");
|
||||
}
|
||||
|
||||
PaymentRequestDialog::~PaymentRequestDialog() = default;
|
37
src/dialog/PaymentRequestDialog.h
Normal file
37
src/dialog/PaymentRequestDialog.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// Copyright (c) 2020-2021, The Monero Project.
|
||||
|
||||
#ifndef FEATHER_PAYMENTREQUESTDIALOG_H
|
||||
#define FEATHER_PAYMENTREQUESTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "appcontext.h"
|
||||
#include "qrcode/QrCode.h"
|
||||
|
||||
namespace Ui {
|
||||
class PaymentRequestDialog;
|
||||
}
|
||||
|
||||
class PaymentRequestDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PaymentRequestDialog(QWidget *parent, QSharedPointer<AppContext> ctx, QString address);
|
||||
~PaymentRequestDialog() override;
|
||||
|
||||
private slots:
|
||||
void updatePaymentRequest();
|
||||
void copyLink();
|
||||
void copyImage();
|
||||
void saveImage();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::PaymentRequestDialog> ui;
|
||||
QSharedPointer<AppContext> m_ctx;
|
||||
QString m_address;
|
||||
QrCode *m_qrCode;
|
||||
};
|
||||
|
||||
#endif //FEATHER_PAYMENTREQUESTDIALOG_H
|
203
src/dialog/PaymentRequestDialog.ui
Normal file
203
src/dialog/PaymentRequestDialog.ui
Normal file
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PaymentRequestDialog</class>
|
||||
<widget class="QDialog" name="PaymentRequestDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>658</width>
|
||||
<height>761</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Create Payment Request</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QrCodeWidget" name="qrWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="line_paymentRequestUri">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Amount:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="line_amountXMR">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>XMR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Description:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="line_description"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Your name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="line_recipient"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_copyLink">
|
||||
<property name="text">
|
||||
<string>Copy Link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_copyImage">
|
||||
<property name="text">
|
||||
<string>Copy Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_saveImage">
|
||||
<property name="text">
|
||||
<string>Save Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QrCodeWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/QrCodeWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>PaymentRequestDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>PaymentRequestDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -1150,6 +1150,14 @@ QVariantMap Wallet::parse_uri_to_object(const QString &uri) const
|
|||
return result;
|
||||
}
|
||||
|
||||
QString Wallet::make_uri(const QString &address, quint64 &amount, const QString &description,
|
||||
const QString &recipient) const
|
||||
{
|
||||
std::string error;
|
||||
std::string uri = m_walletImpl->make_uri(address.toStdString(), "", amount, description.toStdString(), recipient.toStdString(), error);
|
||||
return QString::fromStdString(uri);
|
||||
}
|
||||
|
||||
bool Wallet::rescanSpent()
|
||||
{
|
||||
QMutexLocker locker(&m_asyncMutex);
|
||||
|
|
|
@ -390,6 +390,8 @@ public:
|
|||
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;
|
||||
QVariantMap parse_uri_to_object(const QString &uri) const;
|
||||
|
||||
QString make_uri(const QString &address, quint64 &amount, const QString &description, const QString &recipient) const;
|
||||
|
||||
//! Namespace your cacheAttribute keys to avoid collisions
|
||||
bool setCacheAttribute(const QString &key, const QString &val);
|
||||
QString getCacheAttribute(const QString &key) const;
|
||||
|
|
|
@ -57,4 +57,12 @@ void QrCodeWidget::paintEvent(QPaintEvent *event) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QrCodeWidget::hasHeightForWidth() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
int QrCodeWidget::heightForWidth(int w) const {
|
||||
return w;
|
||||
}
|
|
@ -18,6 +18,8 @@ public:
|
|||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
int heightForWidth(int w) const override;
|
||||
bool hasHeightForWidth() const override;
|
||||
|
||||
private:
|
||||
QrCode *m_qrcode = nullptr;
|
||||
|
|
Loading…
Reference in a new issue