forked from dashpay/dash
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathqrimagewidget.cpp
More file actions
149 lines (125 loc) · 4.63 KB
/
qrimagewidget.cpp
File metadata and controls
149 lines (125 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <qt/qrimagewidget.h>
#include <qt/guiutil.h>
#include <QApplication>
#include <QClipboard>
#include <QDrag>
#include <QMenu>
#include <QMimeData>
#include <QMouseEvent>
#include <QPainter>
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h> /* for USE_QRCODE */
#endif
#ifdef USE_QRCODE
#include <qrencode.h>
#endif
QRImageWidget::QRImageWidget(QWidget *parent):
QLabel(parent), contextMenu(nullptr)
{
contextMenu = new QMenu(this);
QAction *saveImageAction = new QAction(tr("&Save Image..."), this);
connect(saveImageAction, &QAction::triggered, this, &QRImageWidget::saveImage);
contextMenu->addAction(saveImageAction);
QAction *copyImageAction = new QAction(tr("&Copy Image"), this);
connect(copyImageAction, &QAction::triggered, this, &QRImageWidget::copyImage);
contextMenu->addAction(copyImageAction);
}
bool QRImageWidget::setQR(const QString& data, const QString& text)
{
#ifdef USE_QRCODE
setText("");
if (data.isEmpty()) return false;
// limit length
if (data.length() > MAX_URI_LENGTH) {
setText(tr("Resulting URI too long, try to reduce the text for label / message."));
return false;
}
QRcode *code = QRcode_encodeString(data.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
if (!code) {
setText(tr("Error encoding URI into QR Code."));
return false;
}
QImage qrImage = QImage(code->width + 6, code->width + 6, QImage::Format_RGB32);
qrImage.fill(GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BACKGROUND_WIDGET));
unsigned char *p = code->data;
for (int y = 0; y < code->width; y++)
{
for (int x = 0; x < code->width; x++)
{
qrImage.setPixel(x + 3, y + 3, ((*p & 1) ? GUIUtil::getThemedQColor(GUIUtil::ThemedColor::QR_PIXEL).rgb() : GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BACKGROUND_WIDGET).rgb()));
p++;
}
}
QRcode_free(code);
// Create the image with respect to the device pixel ratio
int qrAddrImageWidth = QR_IMAGE_SIZE;
int qrAddrImageHeight = QR_IMAGE_SIZE + 20;
qreal scale = qApp->devicePixelRatio();
QImage qrAddrImage = QImage(qrAddrImageWidth * scale, qrAddrImageHeight * scale, QImage::Format_RGB32);
qrAddrImage.setDevicePixelRatio(scale);
QPainter painter(&qrAddrImage);
// Fill the whole image with border color
qrAddrImage.fill(GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BORDER_WIDGET));
// Create a 2px/2px smaller rect and fill it with background color to keep the 1px border with the border color
QRect paddedRect = QRect(1, 1, qrAddrImageWidth - 2, qrAddrImageHeight - 2);
painter.fillRect(paddedRect, GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BACKGROUND_WIDGET));
painter.drawImage(2, 2, qrImage.scaled(QR_IMAGE_SIZE - 4, QR_IMAGE_SIZE - 4));
// calculate ideal font size
QFont font = GUIUtil::getFontNormal();
qreal font_size = GUIUtil::calculateIdealFontSize((paddedRect.width() - 20), text, font);
font.setPointSizeF(font_size);
// paint the address
painter.setFont(font);
painter.setPen(GUIUtil::getThemedQColor(GUIUtil::ThemedColor::QR_PIXEL));
paddedRect.setHeight(QR_IMAGE_SIZE + 3);
painter.drawText(paddedRect, Qt::AlignBottom|Qt::AlignCenter, text);
painter.end();
setPixmap(QPixmap::fromImage(qrAddrImage));
return true;
#else
setText(tr("QR code support not available."));
return false;
#endif
}
QImage QRImageWidget::exportImage()
{
return GUIUtil::GetImage(this);
}
void QRImageWidget::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && GUIUtil::HasPixmap(this)) {
event->accept();
QMimeData *mimeData = new QMimeData;
mimeData->setImageData(exportImage());
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->exec();
} else {
QLabel::mousePressEvent(event);
}
}
void QRImageWidget::saveImage()
{
if (!GUIUtil::HasPixmap(this))
return;
QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), nullptr);
if (!fn.isEmpty())
{
exportImage().save(fn);
}
}
void QRImageWidget::copyImage()
{
if (!GUIUtil::HasPixmap(this))
return;
QApplication::clipboard()->setImage(exportImage());
}
void QRImageWidget::contextMenuEvent(QContextMenuEvent *event)
{
if (!GUIUtil::HasPixmap(this))
return;
contextMenu->exec(event->globalPos());
}