Send: paste Qr code image in pay to field

This commit is contained in:
tobtoht 2021-07-08 00:48:17 +02:00
parent f15eab8c9d
commit fe4d531b73
No known key found for this signature in database
GPG key ID: 1CADD27F41F45C3C
8 changed files with 106 additions and 40 deletions

View file

@ -41,6 +41,7 @@ SendWidget::SendWidget(QSharedPointer<AppContext> 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();

View file

@ -44,6 +44,9 @@ public slots:
void onInitiateTransaction();
void onEndTransaction();
private slots:
void onDataPasted(const QString &data);
private:
void setupComboBox();
double amountDouble();

View file

@ -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<QString> &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<QString> &unknown_parameters, QString &error) const
{
std::string s_address, s_payment_id, s_tx_description, s_recipient_name, s_error;
std::vector<std::string> 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<QString> 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);

View file

@ -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<QString> &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<QString> &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);

View file

@ -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<QString> &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<QString> 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)
{

View file

@ -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<QString> &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);

View file

@ -4,11 +4,15 @@
#include "PayToEdit.h"
#include <QtGlobal>
#include <QApplication>
#include <QClipboard>
#include <QMimeData>
#include <QScrollBar>
#include <QtGlobal>
#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<QImage>(mimeData->imageData());
}
else if (mimeData->hasUrls()) {
QList<QUrl> 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();

View file

@ -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);