LCOV - code coverage report
Current view: top level - src/qt - qrimagewidget.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 77 0.0 %
Date: 2020-09-26 01:30:44 Functions: 0 8 0.0 %

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

Generated by: LCOV version 1.15