]> Nutra Git (v2) - gamesguru/feather.git/commitdiff
PaymentRequestDialog
authortobtoht <thotbot@protonmail.com>
Fri, 1 Oct 2021 17:10:46 +0000 (19:10 +0200)
committertobtoht <thotbot@protonmail.com>
Fri, 1 Oct 2021 17:10:46 +0000 (19:10 +0200)
src/ReceiveWidget.cpp
src/ReceiveWidget.h
src/ReceiveWidget.ui
src/SendWidget.cpp
src/dialog/PaymentRequestDialog.cpp [new file with mode: 0644]
src/dialog/PaymentRequestDialog.h [new file with mode: 0644]
src/dialog/PaymentRequestDialog.ui [new file with mode: 0644]
src/libwalletqt/Wallet.cpp
src/libwalletqt/Wallet.h
src/widgets/QrCodeWidget.cpp
src/widgets/QrCodeWidget.h

index 477e51cf4355e53692a0fea9958a8a5abae15c7e..f583af431ea9657bec8a173555df95a01d4f29ad 100644 (file)
@@ -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();
     }
 }
 
index 23ee78b1b287f21c662d804dc49cc174042a2566..e01f93fae04660e15a5f484b6c7e0720a1eebb92 100644 (file)
@@ -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);
index 0d420817af9eef340c1de2c75bdb71ac20edfbf3..b84ed585ef9c90c230a8901c5b042a35b2beda4f 100644 (file)
          </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">
index b460a083cf2dc72f983aa0bee4268237f7ed96cb..92f9a34c626f5bb8464a12adb5cda64a555b1751 100644 (file)
@@ -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);
diff --git a/src/dialog/PaymentRequestDialog.cpp b/src/dialog/PaymentRequestDialog.cpp
new file mode 100644 (file)
index 0000000..4cf38ee
--- /dev/null
@@ -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;
\ No newline at end of file
diff --git a/src/dialog/PaymentRequestDialog.h b/src/dialog/PaymentRequestDialog.h
new file mode 100644 (file)
index 0000000..c109d0a
--- /dev/null
@@ -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
diff --git a/src/dialog/PaymentRequestDialog.ui b/src/dialog/PaymentRequestDialog.ui
new file mode 100644 (file)
index 0000000..5b4dac2
--- /dev/null
@@ -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>
index f0dd9f38cbe44546de50760c79e85a84aed2c2e3..ea1d844db3154fbf0a2adc7e02058edb3ac8d668 100644 (file)
@@ -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);
index 1e419450f96d7698c44c5813c2c385a04fd50ca9..f54e8c77a3dab24e5f2949e8d36dc0a566990d42 100644 (file)
@@ -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;
index e82902b31ac074a38e57989149a1a4eea3cd9896..ffc17af647ff99fccc58245f3c4f30fe93de0c72 100644 (file)
@@ -57,4 +57,12 @@ void QrCodeWidget::paintEvent(QPaintEvent *event) {
             }
         }
     }
+}
+
+bool QrCodeWidget::hasHeightForWidth() const {
+    return true;
+}
+
+int QrCodeWidget::heightForWidth(int w) const {
+    return w;
 }
\ No newline at end of file
index 855936e335d51587893a7b40f0558fee8312c898..f86c81dd03195c92aead3541cda21c1b7aa99551 100644 (file)
@@ -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;