Skip to content

Commit fc92984

Browse files
committed
GUI: Move QRImageWidget to its own file-pair
1 parent 77851ab commit fc92984

File tree

7 files changed

+191
-165
lines changed

7 files changed

+191
-165
lines changed

src/Makefile.qt.include

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ QT_MOC_CPP = \
140140
qt/moc_overviewpage.cpp \
141141
qt/moc_peertablemodel.cpp \
142142
qt/moc_paymentserver.cpp \
143+
qt/moc_qrimagewidget.cpp \
143144
qt/moc_qvalidatedlineedit.cpp \
144145
qt/moc_qvaluecombobox.cpp \
145146
qt/moc_receivecoinsdialog.cpp \
@@ -220,6 +221,7 @@ BITCOIN_QT_H = \
220221
qt/paymentserver.h \
221222
qt/peertablemodel.h \
222223
qt/platformstyle.h \
224+
qt/qrimagewidget.h \
223225
qt/qvalidatedlineedit.h \
224226
qt/qvaluecombobox.h \
225227
qt/receivecoinsdialog.h \
@@ -340,6 +342,7 @@ BITCOIN_QT_WALLET_CPP = \
340342
qt/openuridialog.cpp \
341343
qt/overviewpage.cpp \
342344
qt/paymentserver.cpp \
345+
qt/qrimagewidget.cpp \
343346
qt/receivecoinsdialog.cpp \
344347
qt/receiverequestdialog.cpp \
345348
qt/recentrequeststablemodel.cpp \

src/qt/forms/receiverequestdialog.ui

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
<customwidget>
128128
<class>QRImageWidget</class>
129129
<extends>QLabel</extends>
130-
<header>qt/receiverequestdialog.h</header>
130+
<header>qt/qrimagewidget.h</header>
131131
</customwidget>
132132
</customwidgets>
133133
<resources/>

src/qt/guiconstants.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,6 @@ static const bool DEFAULT_SPLASHSCREEN = true;
3737
*/
3838
static const int TOOLTIP_WRAP_THRESHOLD = 80;
3939

40-
/* Maximum allowed URI length */
41-
static const int MAX_URI_LENGTH = 255;
42-
43-
/* QRCodeDialog -- size of exported QR Code image */
44-
#define QR_IMAGE_SIZE 300
45-
4640
/* Number of frames in spinner animation */
4741
#define SPINNER_FRAMES 36
4842

src/qt/qrimagewidget.cpp

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Copyright (c) 2011-2018 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qt/qrimagewidget.h>
6+
7+
#include <qt/guiutil.h>
8+
9+
#include <QApplication>
10+
#include <QClipboard>
11+
#include <QDrag>
12+
#include <QMenu>
13+
#include <QMimeData>
14+
#include <QMouseEvent>
15+
#include <QPainter>
16+
17+
#if defined(HAVE_CONFIG_H)
18+
#include <config/bitcoin-config.h> /* for USE_QRCODE */
19+
#endif
20+
21+
#ifdef USE_QRCODE
22+
#include <qrencode.h>
23+
#endif
24+
25+
QRImageWidget::QRImageWidget(QWidget *parent):
26+
QLabel(parent), contextMenu(nullptr)
27+
{
28+
contextMenu = new QMenu(this);
29+
QAction *saveImageAction = new QAction(tr("&Save Image..."), this);
30+
connect(saveImageAction, &QAction::triggered, this, &QRImageWidget::saveImage);
31+
contextMenu->addAction(saveImageAction);
32+
QAction *copyImageAction = new QAction(tr("&Copy Image"), this);
33+
connect(copyImageAction, &QAction::triggered, this, &QRImageWidget::copyImage);
34+
contextMenu->addAction(copyImageAction);
35+
}
36+
37+
bool QRImageWidget::setQR(const QString& data, const QString& text)
38+
{
39+
#ifdef USE_QRCODE
40+
setText("");
41+
if (data.isEmpty()) return false;
42+
43+
// limit length
44+
if (data.length() > MAX_URI_LENGTH) {
45+
setText(tr("Resulting URI too long, try to reduce the text for label / message."));
46+
return false;
47+
}
48+
49+
QRcode *code = QRcode_encodeString(data.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
50+
51+
if (!code) {
52+
setText(tr("Error encoding URI into QR Code."));
53+
return false;
54+
}
55+
56+
QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
57+
qrImage.fill(0xffffff);
58+
unsigned char *p = code->data;
59+
for (int y = 0; y < code->width; ++y) {
60+
for (int x = 0; x < code->width; ++x) {
61+
qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
62+
++p;
63+
}
64+
}
65+
QRcode_free(code);
66+
67+
QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE + (text.isEmpty() ? 0 : 20), QImage::Format_RGB32);
68+
qrAddrImage.fill(0xffffff);
69+
QPainter painter(&qrAddrImage);
70+
painter.drawImage(0, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE));
71+
72+
if (!text.isEmpty()) {
73+
QFont font = GUIUtil::fixedPitchFont();
74+
QRect paddedRect = qrAddrImage.rect();
75+
76+
// calculate ideal font size
77+
qreal font_size = GUIUtil::calculateIdealFontSize(paddedRect.width() - 20, text, font);
78+
font.setPointSizeF(font_size);
79+
80+
painter.setFont(font);
81+
paddedRect.setHeight(QR_IMAGE_SIZE+12);
82+
painter.drawText(paddedRect, Qt::AlignBottom|Qt::AlignCenter, text);
83+
}
84+
85+
painter.end();
86+
setPixmap(QPixmap::fromImage(qrAddrImage));
87+
88+
return true;
89+
#else
90+
setText(tr("QR code support not available."));
91+
return false;
92+
#endif
93+
}
94+
95+
QImage QRImageWidget::exportImage()
96+
{
97+
if(!pixmap())
98+
return QImage();
99+
return pixmap()->toImage();
100+
}
101+
102+
void QRImageWidget::mousePressEvent(QMouseEvent *event)
103+
{
104+
if(event->button() == Qt::LeftButton && pixmap())
105+
{
106+
event->accept();
107+
QMimeData *mimeData = new QMimeData;
108+
mimeData->setImageData(exportImage());
109+
110+
QDrag *drag = new QDrag(this);
111+
drag->setMimeData(mimeData);
112+
drag->exec();
113+
} else {
114+
QLabel::mousePressEvent(event);
115+
}
116+
}
117+
118+
void QRImageWidget::saveImage()
119+
{
120+
if(!pixmap())
121+
return;
122+
QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), nullptr);
123+
if (!fn.isEmpty())
124+
{
125+
exportImage().save(fn);
126+
}
127+
}
128+
129+
void QRImageWidget::copyImage()
130+
{
131+
if(!pixmap())
132+
return;
133+
QApplication::clipboard()->setImage(exportImage());
134+
}
135+
136+
void QRImageWidget::contextMenuEvent(QContextMenuEvent *event)
137+
{
138+
if(!pixmap())
139+
return;
140+
contextMenu->exec(event->globalPos());
141+
}

src/qt/qrimagewidget.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2011-2018 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QT_QRIMAGEWIDGET_H
6+
#define BITCOIN_QT_QRIMAGEWIDGET_H
7+
8+
#include <QImage>
9+
#include <QLabel>
10+
11+
/* Maximum allowed URI length */
12+
static const int MAX_URI_LENGTH = 255;
13+
14+
/* Size of exported QR Code image */
15+
static const int QR_IMAGE_SIZE = 300;
16+
17+
QT_BEGIN_NAMESPACE
18+
class QMenu;
19+
QT_END_NAMESPACE
20+
21+
/* Label widget for QR code. This image can be dragged, dropped, copied and saved
22+
* to disk.
23+
*/
24+
class QRImageWidget : public QLabel
25+
{
26+
Q_OBJECT
27+
28+
public:
29+
explicit QRImageWidget(QWidget *parent = nullptr);
30+
bool setQR(const QString& data, const QString& text = "");
31+
QImage exportImage();
32+
33+
public Q_SLOTS:
34+
void saveImage();
35+
void copyImage();
36+
37+
protected:
38+
virtual void mousePressEvent(QMouseEvent *event);
39+
virtual void contextMenuEvent(QContextMenuEvent *event);
40+
41+
private:
42+
QMenu *contextMenu;
43+
};
44+
45+
#endif // BITCOIN_QT_QRIMAGEWIDGET_H

src/qt/receiverequestdialog.cpp

Lines changed: 1 addition & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -6,143 +6,17 @@
66
#include <qt/forms/ui_receiverequestdialog.h>
77

88
#include <qt/bitcoinunits.h>
9-
#include <qt/guiconstants.h>
109
#include <qt/guiutil.h>
1110
#include <qt/optionsmodel.h>
11+
#include <qt/qrimagewidget.h>
1212

1313
#include <QClipboard>
14-
#include <QDrag>
15-
#include <QMenu>
16-
#include <QMimeData>
17-
#include <QMouseEvent>
1814
#include <QPixmap>
1915

2016
#if defined(HAVE_CONFIG_H)
2117
#include <config/bitcoin-config.h> /* for USE_QRCODE */
2218
#endif
2319

24-
#ifdef USE_QRCODE
25-
#include <qrencode.h>
26-
#endif
27-
28-
QRImageWidget::QRImageWidget(QWidget *parent):
29-
QLabel(parent), contextMenu(nullptr)
30-
{
31-
contextMenu = new QMenu(this);
32-
QAction *saveImageAction = new QAction(tr("&Save Image..."), this);
33-
connect(saveImageAction, &QAction::triggered, this, &QRImageWidget::saveImage);
34-
contextMenu->addAction(saveImageAction);
35-
QAction *copyImageAction = new QAction(tr("&Copy Image"), this);
36-
connect(copyImageAction, &QAction::triggered, this, &QRImageWidget::copyImage);
37-
contextMenu->addAction(copyImageAction);
38-
}
39-
40-
bool QRImageWidget::setQR(const QString& data, const QString& text)
41-
{
42-
#ifdef USE_QRCODE
43-
setText("");
44-
if (data.isEmpty()) return false;
45-
46-
// limit length
47-
if (data.length() > MAX_URI_LENGTH) {
48-
setText(tr("Resulting URI too long, try to reduce the text for label / message."));
49-
return false;
50-
}
51-
52-
QRcode *code = QRcode_encodeString(data.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
53-
54-
if (!code) {
55-
setText(tr("Error encoding URI into QR Code."));
56-
return false;
57-
}
58-
59-
QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
60-
qrImage.fill(0xffffff);
61-
unsigned char *p = code->data;
62-
for (int y = 0; y < code->width; ++y) {
63-
for (int x = 0; x < code->width; ++x) {
64-
qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
65-
++p;
66-
}
67-
}
68-
QRcode_free(code);
69-
70-
QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE + (text.isEmpty() ? 0 : 20), QImage::Format_RGB32);
71-
qrAddrImage.fill(0xffffff);
72-
QPainter painter(&qrAddrImage);
73-
painter.drawImage(0, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE));
74-
75-
if (!text.isEmpty()) {
76-
QFont font = GUIUtil::fixedPitchFont();
77-
QRect paddedRect = qrAddrImage.rect();
78-
79-
// calculate ideal font size
80-
qreal font_size = GUIUtil::calculateIdealFontSize(paddedRect.width() - 20, text, font);
81-
font.setPointSizeF(font_size);
82-
83-
painter.setFont(font);
84-
paddedRect.setHeight(QR_IMAGE_SIZE+12);
85-
painter.drawText(paddedRect, Qt::AlignBottom|Qt::AlignCenter, text);
86-
}
87-
88-
painter.end();
89-
setPixmap(QPixmap::fromImage(qrAddrImage));
90-
91-
return true;
92-
#else
93-
setText(tr("QR code support not available."));
94-
return false;
95-
#endif
96-
}
97-
98-
QImage QRImageWidget::exportImage()
99-
{
100-
if(!pixmap())
101-
return QImage();
102-
return pixmap()->toImage();
103-
}
104-
105-
void QRImageWidget::mousePressEvent(QMouseEvent *event)
106-
{
107-
if(event->button() == Qt::LeftButton && pixmap())
108-
{
109-
event->accept();
110-
QMimeData *mimeData = new QMimeData;
111-
mimeData->setImageData(exportImage());
112-
113-
QDrag *drag = new QDrag(this);
114-
drag->setMimeData(mimeData);
115-
drag->exec();
116-
} else {
117-
QLabel::mousePressEvent(event);
118-
}
119-
}
120-
121-
void QRImageWidget::saveImage()
122-
{
123-
if(!pixmap())
124-
return;
125-
QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), nullptr);
126-
if (!fn.isEmpty())
127-
{
128-
exportImage().save(fn);
129-
}
130-
}
131-
132-
void QRImageWidget::copyImage()
133-
{
134-
if(!pixmap())
135-
return;
136-
QApplication::clipboard()->setImage(exportImage());
137-
}
138-
139-
void QRImageWidget::contextMenuEvent(QContextMenuEvent *event)
140-
{
141-
if(!pixmap())
142-
return;
143-
contextMenu->exec(event->globalPos());
144-
}
145-
14620
ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent) :
14721
QDialog(parent),
14822
ui(new Ui::ReceiveRequestDialog),

0 commit comments

Comments
 (0)