bitcoin/src/qt/qrimagewidget.cpp
MarcoFalke 0a267f4eb8
Merge bitcoin-core/gui#46: refactor: Fix deprecation warnings when building against Qt 5.15
705c1f0648c72aa97e0ee699ff9a3da23fc9bd61 qt, refactor: Fix 'buttonClicked is deprecated' warnings (Hennadii Stepanov)
c2f4e5ea1d6f01713ac69aaf6018884028aa55bd qt, refactor: Fix 'split is deprecated' warnings (Hennadii Stepanov)
8e12d6996116e786e928077b22d9f47cee27319e qt, refactor: Fix 'QFlags is deprecated' warnings (Hennadii Stepanov)
fa5749c805878304c107bcae0ae5ffa401dc7c4d qt, refactor: Fix 'pixmap is deprecated' warnings (Hennadii Stepanov)
b02264cb5dfcef50eec8a6346471cbaa25370e00 qt, refactor: Fix 'QDateTime is deprecated' warnings (Hennadii Stepanov)

Pull request description:

  [What's New in Qt 5.15](https://doc.qt.io/qt-5/whatsnew515.html#deprecated-modules):
  > To help preparing for the transition to Qt 6, numerous classes and member functions that will be removed from Qt 6.0 have been marked as deprecated in the Qt 5.15 release.

  Fixes #36

ACKs for top commit:
  jonasschnelli:
    utACK 705c1f0648c72aa97e0ee699ff9a3da23fc9bd61
  promag:
    Tested ACK 705c1f0648c72aa97e0ee699ff9a3da23fc9bd61 on macos with Apple clang version 11.0.3 (clang-1103.0.32.62) and brew qt 5.15.1.

Tree-SHA512: 29e00535b4583ceec0dfb29612e86ee29bdea13651b548c6d22167917a4a10464af49160a12b05151030699f690f437ebb9c4ae9f130f66a722415222165b44f
2020-11-19 19:04:22 +01:00

143 lines
4.1 KiB
C++

// 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 <QFontDatabase>
#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 + 8, code->width + 8, QImage::Format_RGB32);
qrImage.fill(0xffffff);
unsigned char *p = code->data;
for (int y = 0; y < code->width; ++y) {
for (int x = 0; x < code->width; ++x) {
qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
++p;
}
}
QRcode_free(code);
const int qr_image_size = QR_IMAGE_SIZE + (text.isEmpty() ? 0 : 2 * QR_IMAGE_MARGIN);
QImage qrAddrImage(qr_image_size, qr_image_size, QImage::Format_RGB32);
qrAddrImage.fill(0xffffff);
{
QPainter painter(&qrAddrImage);
painter.drawImage(QR_IMAGE_MARGIN, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE));
if (!text.isEmpty()) {
QRect paddedRect = qrAddrImage.rect();
paddedRect.setHeight(QR_IMAGE_SIZE + QR_IMAGE_TEXT_MARGIN);
QFont font = GUIUtil::fixedPitchFont();
font.setStretch(QFont::SemiCondensed);
font.setLetterSpacing(QFont::AbsoluteSpacing, 1);
const qreal font_size = GUIUtil::calculateIdealFontSize(paddedRect.width() - 2 * QR_IMAGE_TEXT_MARGIN, text, font);
font.setPointSizeF(font_size);
painter.setFont(font);
painter.drawText(paddedRect, Qt::AlignBottom | Qt::AlignCenter, text);
}
}
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());
}