qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
qrwidget.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2015-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 
21 #include "qrwidget.h"
22 #include <QBuffer>
23 #include <QDebug>
24 #include <QImage>
25 #include <QPainter>
26 #include <qrencode.h>
27 
28 #if defined(Q_OS_WIN32) || defined(Q_OS_HAIKU)
29 #include <errno.h>
30 #else
31 #include <sys/errno.h>
32 #endif
33 
39 QRWidget::QRWidget(QWidget* parent)
40  : QWidget(parent)
41  , data("0")
42 // Note: The encoding fails with empty string so I just default to something else.
43 // Use the setQRData() call to change this.
44 {
45  // size of the qimage might be problematic in the future, but it works for me
46  size.setWidth(480);
47  size.setHeight(480);
48  image = new QImage(size, QImage::Format_RGB32);
49 }
50 
52 {
53  delete image;
54 }
55 
56 void QRWidget::setQRData(const QString& data)
57 {
58  this->data = data;
59  paintImage();
60 }
61 
63 {
64  return image;
65 }
66 
72 bool QRWidget::saveImage(QString path)
73 {
74  // 0 - image format same as file extension, 75-quality, png file is ~6.3kb
75  return image->save(path, nullptr, 75);
76 }
77 
78 // http://stackoverflow.com/questions/21400254/how-to-draw-a-qr-code-with-qt-in-native-c-c
80 {
81  QPainter painter(image);
82  // NOTE: I have hardcoded some parameters here that would make more sense as variables.
83  // ECLEVEL_M is much faster recognizable by barcodescanner any any other type
84  // https://fukuchi.org/works/qrencode/manual/qrencode_8h.html#a4cebc3c670efe1b8866b14c42737fc8f
85  // any mode other than QR_MODE_8 or QR_MODE_KANJI results in EINVAL. First 1 is version, second
86  // is case sensitivity
87  const std::string dataString = data.toStdString();
88  QRcode* qr = QRcode_encodeString(dataString.c_str(), 1, QR_ECLEVEL_M, QR_MODE_8, 1);
89 
90  if (qr != nullptr) {
91  QColor fg("black");
92  QColor bg("white");
93  painter.setBrush(bg);
94  painter.setPen(Qt::NoPen);
95  painter.drawRect(0, 0, size.width(), size.height());
96  painter.setBrush(fg);
97  painter.scale(0.96, 0.96);
98  painter.translate(size.width() * 0.02, size.height() * 0.02);
99  const int s = qr->width > 0 ? qr->width : 1;
100  const double w = width();
101  const double h = height();
102  const double aspect = w / h;
103  const double scale = ((aspect > 1.0) ? h : w) / s;
104 
105  for (int y = 0; y < s; ++y) {
106  const int yy = y * s;
107  for (int x = 0; x < s; ++x) {
108  const int xx = yy + x;
109  const unsigned char b = qr->data[xx];
110  if (b & 0x01) {
111  const double rx1 = x * scale, ry1 = y * scale;
112  QRectF r(rx1, ry1, scale, scale);
113  painter.drawRects(&r, 1);
114  }
115  }
116  }
117  QRcode_free(qr);
118  } else {
119  QColor error("red");
120  painter.setBrush(error);
121  painter.drawRect(0, 0, width(), height());
122  qDebug() << "QR FAIL: " << strerror(errno);
123  }
124 
125  qr = nullptr;
126 }
QRWidget::~QRWidget
~QRWidget()
Definition: qrwidget.cpp:51
QRWidget::setQRData
void setQRData(const QString &data)
Definition: qrwidget.cpp:56
QRWidget::data
QString data
Definition: qrwidget.h:37
QRWidget::paintImage
void paintImage()
Definition: qrwidget.cpp:79
QRWidget::image
QImage * image
Definition: qrwidget.h:39
QRWidget::size
QSize size
Definition: qrwidget.h:40
QRWidget::saveImage
bool saveImage(QString path)
QRWidget::saveImage.
Definition: qrwidget.cpp:72
QRWidget::QRWidget
QRWidget(QWidget *parent=nullptr)
Definition: qrwidget.cpp:39
qrwidget.h
QRWidget::getImage
QImage * getImage()
Definition: qrwidget.cpp:62