diff --git a/src/ReceiveWidget.cpp b/src/ReceiveWidget.cpp index 2dbeba5..477e51c 100644 --- a/src/ReceiveWidget.cpp +++ b/src/ReceiveWidget.cpp @@ -209,9 +209,8 @@ void ReceiveWidget::showQrCodeDialog() { } QString address = index.model()->data(index.siblingAtColumn(SubaddressModel::Address), Qt::UserRole).toString(); QrCode qr(address, QrCode::Version::AUTO, QrCode::ErrorCorrectionLevel::HIGH); - auto *dialog = new QrCodeDialog(this, qr, "Address"); - dialog->exec(); - dialog->deleteLater(); + QrCodeDialog dialog{this, &qr, "Address"}; + dialog.exec(); } QStringList ReceiveWidget::getHiddenAddresses() { diff --git a/src/dialog/QrCodeDialog.cpp b/src/dialog/QrCodeDialog.cpp index 5cbc442..4b1c7cf 100644 --- a/src/dialog/QrCodeDialog.cpp +++ b/src/dialog/QrCodeDialog.cpp @@ -8,15 +8,16 @@ #include #include -QrCodeDialog::QrCodeDialog(QWidget *parent, const QrCode &qrCode, const QString &title) +QrCodeDialog::QrCodeDialog(QWidget *parent, QrCode *qrCode, const QString &title) : QDialog(parent) , ui(new Ui::QrCodeDialog) { ui->setupUi(this); this->setWindowTitle(title); - m_pixmap = qrCode.toPixmap(1).scaled(500, 500, Qt::KeepAspectRatio); - ui->QrCode->setPixmap(m_pixmap); + ui->qrWidget->setQrCode(qrCode); + + m_pixmap = qrCode->toPixmap(1).scaled(500, 500, Qt::KeepAspectRatio); connect(ui->btn_CopyImage, &QPushButton::clicked, this, &QrCodeDialog::copyImage); connect(ui->btn_Save, &QPushButton::clicked, this, &QrCodeDialog::saveImage); @@ -24,12 +25,7 @@ QrCodeDialog::QrCodeDialog(QWidget *parent, const QrCode &qrCode, const QString accept(); }); - this->adjustSize(); -} - -void QrCodeDialog::setQrCode(const QrCode &qrCode) { - m_pixmap = qrCode.toPixmap(1).scaled(500, 500, Qt::KeepAspectRatio); - ui->QrCode->setPixmap(m_pixmap); + this->resize(500, 500); } void QrCodeDialog::copyImage() { diff --git a/src/dialog/QrCodeDialog.h b/src/dialog/QrCodeDialog.h index 1420f9b..706b120 100644 --- a/src/dialog/QrCodeDialog.h +++ b/src/dialog/QrCodeDialog.h @@ -7,6 +7,7 @@ #include #include "qrcode/QrCode.h" +#include "widgets/QrCodeWidget.h" namespace Ui { class QrCodeDialog; @@ -17,9 +18,8 @@ class QrCodeDialog : public QDialog Q_OBJECT public: - explicit QrCodeDialog(QWidget *parent, const QrCode &qrCode, const QString &title = "Qr Code"); + explicit QrCodeDialog(QWidget *parent, QrCode *qrCode, const QString &title = "Qr Code"); ~QrCodeDialog() override; - void setQrCode(const QrCode &qrCode); private: void copyImage(); @@ -29,5 +29,4 @@ private: QPixmap m_pixmap; }; - #endif //FEATHER_QRCODEDIALOG_H diff --git a/src/dialog/QrCodeDialog.ui b/src/dialog/QrCodeDialog.ui index c160dc9..50a4790 100644 --- a/src/dialog/QrCodeDialog.ui +++ b/src/dialog/QrCodeDialog.ui @@ -6,8 +6,8 @@ 0 0 - 522 - 562 + 520 + 446 @@ -15,22 +15,19 @@ - + - + 0 0 - 500 - 500 + 150 + 150 - - QrCode - @@ -88,6 +85,14 @@ + + + QrCodeWidget + QWidget +
widgets/QrCodeWidget.h
+ 1 +
+
diff --git a/src/dialog/TxConfAdvDialog.cpp b/src/dialog/TxConfAdvDialog.cpp index ea88dc1..fda8f53 100644 --- a/src/dialog/TxConfAdvDialog.cpp +++ b/src/dialog/TxConfAdvDialog.cpp @@ -154,9 +154,8 @@ void TxConfAdvDialog::unsignedQrCode() { } QrCode qr(m_tx->unsignedTxToBin(), QrCode::Version::AUTO, QrCode::ErrorCorrectionLevel::LOW); - auto *dialog = new QrCodeDialog(this, qr, "Unsigned Transaction"); - dialog->exec(); - dialog->deleteLater(); + QrCodeDialog dialog{this, &qr, "Unsigned Transaction"}; + dialog.exec(); } void TxConfAdvDialog::unsignedCopy() { diff --git a/src/qrcode/QrCode.cpp b/src/qrcode/QrCode.cpp index 6769540..7326826 100644 --- a/src/qrcode/QrCode.cpp +++ b/src/qrcode/QrCode.cpp @@ -164,4 +164,20 @@ QPixmap QrCode::toPixmap(const int margin) const painter.end(); return pixmap; -} \ No newline at end of file +} + +int QrCode::width() { + if (!isValid()) { + return 0; + } + + return d_ptr->m_qrcode->width; +} + +unsigned char* QrCode::data() { + if (!isValid()) { + return nullptr; + } + + return d_ptr->m_qrcode->data; +} diff --git a/src/qrcode/QrCode.h b/src/qrcode/QrCode.h index 50173b4..879be77 100644 --- a/src/qrcode/QrCode.h +++ b/src/qrcode/QrCode.h @@ -71,6 +71,9 @@ public: void writeSvg(QIODevice* outputDevice, const int dpi, const int margin = 4) const; QPixmap toPixmap(const int margin = 4) const; + int width(); + unsigned char* data(); + private: void init(const QString& data, const Version version, const ErrorCorrectionLevel ecl, const bool caseSensitive); diff --git a/src/widgets/QrCodeWidget.cpp b/src/widgets/QrCodeWidget.cpp new file mode 100644 index 0000000..e82902b --- /dev/null +++ b/src/widgets/QrCodeWidget.cpp @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2020-2021, The Monero Project. + +#include "QrCodeWidget.h" + +#include +#include +#include + +QrCodeWidget::QrCodeWidget(QWidget *parent) : QWidget(parent) +{ +} + +void QrCodeWidget::setQrCode(QrCode *qrCode) { + m_qrcode = qrCode; + + int k = m_qrcode->width(); + this->setMinimumSize(k*5, k*5); + + this->update(); +} + +void QrCodeWidget::paintEvent(QPaintEvent *event) { + // Implementation adapted from Electrum: qrcodewidget.py + if (!m_qrcode) { + return; + } + + QColor black{0, 0, 0, 255}; + QColor white{255, 255, 255, 255}; + QPen blackPen{black}; + blackPen.setJoinStyle(Qt::MiterJoin); + + QPainter painter(this); + + auto r = painter.viewport(); + int k = m_qrcode->width(); + int margin = 10; + int framesize = std::min(r.width(), r.height()); + int boxsize = int((framesize - (2*margin)) / k); + int size = k*boxsize; + int left = (framesize - size)/2; + int top = (framesize - size)/2; + + painter.setBrush(white); + painter.setPen(white); + painter.drawRect(0, 0, framesize, framesize); + + painter.setBrush(black); + painter.setPen(blackPen); + + unsigned char* dot = m_qrcode->data(); + for (int row = 0; row < k; row++) { + for (int column = 0; column < k; column++) { + if (quint8(0x01) == (static_cast(*dot++) & quint8(0x01))) { + painter.drawRect(int(left+(column*boxsize)), int(top+(row*boxsize)), boxsize - 1, boxsize - 1); + } + } + } +} \ No newline at end of file diff --git a/src/widgets/QrCodeWidget.h b/src/widgets/QrCodeWidget.h new file mode 100644 index 0000000..855936e --- /dev/null +++ b/src/widgets/QrCodeWidget.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2020-2021, The Monero Project. + +#ifndef FEATHER_QRCODEWIDGET_H +#define FEATHER_QRCODEWIDGET_H + +#include + +#include "qrcode/QrCode.h" + +class QrCodeWidget : public QWidget +{ + Q_OBJECT + +public: + explicit QrCodeWidget(QWidget *parent = nullptr); + void setQrCode(QrCode *qrCode); + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + QrCode *m_qrcode = nullptr; +}; + +#endif //FEATHER_QRCODEWIDGET_H