diff --git a/src/SendWidget.cpp b/src/SendWidget.cpp index 1d24138..c767170 100644 --- a/src/SendWidget.cpp +++ b/src/SendWidget.cpp @@ -41,6 +41,7 @@ SendWidget::SendWidget(QSharedPointer ctx, QWidget *parent) connect(ui->lineAmount, &QLineEdit::textChanged, this, &SendWidget::amountEdited); connect(ui->lineAddress, &QPlainTextEdit::textChanged, this, &SendWidget::addressEdited); connect(ui->btn_openAlias, &QPushButton::clicked, this, &SendWidget::aliasClicked); + connect(ui->lineAddress, &PayToEdit::dataPasted, this, &SendWidget::onDataPasted); ui->label_conversionAmount->setText(""); ui->label_conversionAmount->hide(); ui->btn_openAlias->hide(); @@ -274,6 +275,25 @@ void SendWidget::onEndTransaction() { ui->btnSend->setEnabled(true); } +void SendWidget::onDataPasted(const QString &data) { + if (!data.isEmpty()) { + QVariantMap uriData = m_ctx->wallet->parse_uri_to_object(data); + if (!uriData.contains("error")) { + if (uriData.contains("address")) + ui->lineAddress->setText(uriData.value("address").toString()); + if (uriData.contains("amount")) + ui->lineAmount->setText(uriData.value("amount").toString()); + if (uriData.contains("tx_description")) + ui->lineDescription->setText(uriData.value("tx_description").toString()); + } else { + ui->lineAddress->setText(data); + } + } + else { + QMessageBox::warning(this, "Error", "No Qr Code found."); + } +} + void SendWidget::setupComboBox() { ui->comboCurrencySelection->clear(); diff --git a/src/SendWidget.h b/src/SendWidget.h index 7826318..31c9c0a 100644 --- a/src/SendWidget.h +++ b/src/SendWidget.h @@ -44,6 +44,9 @@ public slots: void onInitiateTransaction(); void onEndTransaction(); +private slots: + void onDataPasted(const QString &data); + private: void setupComboBox(); double amountDouble(); diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 629d788..98d0d9d 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -1102,7 +1102,8 @@ bool Wallet::verifySignedMessage(const QString &message, const QString &address, return m_walletImpl->verifySignedMessage(message.toStdString(), address.toStdString(), signature.toStdString()); } } -bool Wallet::parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector &unknown_parameters, QString &error) + +bool Wallet::parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector &unknown_parameters, QString &error) const { std::string s_address, s_payment_id, s_tx_description, s_recipient_name, s_error; std::vector s_unknown_parameters; @@ -1120,6 +1121,30 @@ bool Wallet::parse_uri(const QString &uri, QString &address, QString &payment_id return res; } +QVariantMap Wallet::parse_uri_to_object(const QString &uri) const +{ + QString address; + QString payment_id; + uint64_t amount = 0; + QString tx_description; + QString recipient_name; + QVector unknown_parameters; + QString error; + + QVariantMap result; + if (this->parse_uri(uri, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error)) { + result.insert("address", address); + result.insert("payment_id", payment_id); + result.insert("amount", amount > 0 ? QString::fromStdString(Monero::Wallet::displayAmount(amount)) : ""); + result.insert("tx_description", tx_description); + result.insert("recipient_name", recipient_name); + } else { + result.insert("error", error); + } + + return result; +} + bool Wallet::rescanSpent() { QMutexLocker locker(&m_asyncMutex); diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index bcdb65c..49e44eb 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -76,9 +76,9 @@ class Wallet : public QObject, public PassprasePrompter Q_OBJECT public: - Wallet(QObject * parent = nullptr); - Wallet(Monero::Wallet *w, QObject * parent = nullptr); - ~Wallet(); + explicit Wallet(QObject *parent = nullptr); + explicit Wallet(Monero::Wallet *w, QObject * parent = nullptr); + ~Wallet() override; enum Status { Status_Ok = Monero::Wallet::Status_Ok, @@ -384,7 +384,8 @@ public: bool verifySignedMessage(const QString &message, const QString &address, const QString &signature, bool filename = false) const; //! Parse URI - bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector &unknown_parameters, QString &error); + bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector &unknown_parameters, QString &error) const; + QVariantMap parse_uri_to_object(const QString &uri) const; //! Namespace your cacheAttribute keys to avoid collisions bool setCacheAttribute(const QString &key, const QString &val); diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index fbecd33..0c1d655 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -304,38 +304,6 @@ QString WalletManager::resolveOpenAlias(const QString &address) const res = std::string(dnssec_valid ? "true" : "false") + "|" + res; return QString::fromStdString(res); } -bool WalletManager::parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector &unknown_parameters, QString &error) const -{ - QMutexLocker locker(&m_mutex); - // TODO: FIXME -// if (m_currentWallet) -// return m_currentWallet->parse_uri(uri, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error); - return false; -} - -QVariantMap WalletManager::parse_uri_to_object(const QString &uri) const -{ - QString address; - QString payment_id; - uint64_t amount = 0; - QString tx_description; - QString recipient_name; - QVector unknown_parameters; - QString error; - - QVariantMap result; - if (this->parse_uri(uri, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error)) { - result.insert("address", address); - result.insert("payment_id", payment_id); - result.insert("amount", amount > 0 ? displayAmount(amount) : ""); - result.insert("tx_description", tx_description); - result.insert("recipient_name", recipient_name); - } else { - result.insert("error", error); - } - - return result; -} void WalletManager::setLogLevel(int logLevel) { diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index b43f83d..b9086c5 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -143,8 +143,6 @@ public: Q_INVOKABLE qint64 subi(qint64 x, qint64 y) const { return x - y; } Q_INVOKABLE QString resolveOpenAlias(const QString &address) const; - Q_INVOKABLE bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector &unknown_parameters, QString &error) const; - Q_INVOKABLE QVariantMap parse_uri_to_object(const QString &uri) const; // clear/rename wallet cache Q_INVOKABLE static bool clearWalletCache(const QString &fileName); diff --git a/src/widgets/PayToEdit.cpp b/src/widgets/PayToEdit.cpp index a63f41d..1a7fc81 100644 --- a/src/widgets/PayToEdit.cpp +++ b/src/widgets/PayToEdit.cpp @@ -4,11 +4,15 @@ #include "PayToEdit.h" -#include +#include +#include +#include #include +#include #include "libwalletqt/WalletManager.h" #include "model/ModelUtils.h" +#include "qrcode_scanner/QrCodeUtils.h" PayToEdit::PayToEdit(QWidget *parent) : QPlainTextEdit(parent) { @@ -72,6 +76,45 @@ bool PayToEdit::isOpenAlias() { return true; } +void PayToEdit::keyPressEvent(QKeyEvent *event) { + if (event->matches(QKeySequence::Paste)) { + this->pasteEvent(QApplication::clipboard()->mimeData()); + event->accept(); + } + + QPlainTextEdit::keyPressEvent(event); +} + +void PayToEdit::pasteEvent(const QMimeData *mimeData) { + QImage image; + if (mimeData->hasImage()) { + image = qvariant_cast(mimeData->imageData()); + } + else if (mimeData->hasUrls()) { + QList urlList = mimeData->urls(); + if (urlList.count() > 1) { + return; + } + QFileInfo file(urlList.at(0).toLocalFile()); + if (file.exists()) { + image = QImage{file.absoluteFilePath()}; + } + } + else { + return; + } + + if (image.isNull()) { + qDebug() << "Invalid image"; + return; + } + + image.convertTo(QImage::Format_RGB32); + QString result = QrCodeUtils::scanImage(image); + + dataPasted(result); +} + void PayToEdit::checkText() { m_errors.clear(); m_outputs.clear(); diff --git a/src/widgets/PayToEdit.h b/src/widgets/PayToEdit.h index 0b3bfa7..0d698df 100644 --- a/src/widgets/PayToEdit.h +++ b/src/widgets/PayToEdit.h @@ -48,10 +48,18 @@ public: void payToMany(); bool isOpenAlias(); +signals: + void dataPasted(const QString &data); + +protected: + void keyPressEvent(QKeyEvent *event) override; + private: void checkText(); void updateSize(); + void pasteEvent(const QMimeData *mimeData); + PartialTxOutput parseAddressAndAmount(const QString &line); quint64 parseAmount(QString amount); QString parseAddress(QString address);