1
0
mirror of https://github.com/binary-kitchen/doorlockd synced 2024-12-22 02:14:26 +01:00

Added simple Qt Qr widget

This commit is contained in:
Ralf Ramsauer 2015-09-25 13:11:36 +02:00
parent 69dcbe6b59
commit 13b0b8744a
4 changed files with 132 additions and 9 deletions

View File

@ -9,6 +9,11 @@ set(DOORLOCK_VERSION_PATCH 0)
set(DOORLOCK_VERSION "${DOORLOCK_VERSION_MAJOR}.${DOORLOCK_VERSION_MINOR}-${DOORLOCK_VERSION_PATCH}")
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
include_directories(${CMAKE_SOURCE_DIR}/src)
MESSAGE(STATUS "doorlockd version: ${DOORLOCK_VERSION}")
# Get the current working branch
@ -51,6 +56,8 @@ include_directories(${JSON_INCLUDE_DIR})
find_package (Threads)
find_package(Qt5Widgets)
set(DOORLOCKD_SRCS
src/clientmessage.cpp
src/clientmessage.h
@ -80,6 +87,8 @@ set(DOORLOCK_CLIENT_SRCS
src/response.h
src/util.cpp
src/util.h
src/qrwidget.cpp
src/qrwidget.h
src/doorlock-client.cpp
)
@ -88,7 +97,8 @@ add_executable(doorlockd ${DOORLOCKD_SRCS})
target_link_libraries(doorlockd jsoncpp ldap ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
add_executable(doorlock-client ${DOORLOCK_CLIENT_SRCS})
target_link_libraries(doorlock-client jsoncpp ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(doorlock-client jsoncpp ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}
qrencode Qt5::Widgets)
install(TARGETS doorlockd DESTINATION sbin/)
install(TARGETS doorlock-client DESTINATION bin/)

View File

@ -1,6 +1,7 @@
#include <exception>
#include <iostream>
#include <string>
#include <thread>
#include <boost/asio.hpp>
#include <boost/program_options.hpp>
@ -10,6 +11,9 @@
#include "logger.h"
#include "response.h"
#include <QApplication>
#include "qrwidget.h"
// Info about doorlock-client version
const static std::string version =
"doorlock-client-" DOORLOCK_VERSION;
@ -29,20 +33,37 @@ const static std::string subscriptionCommand =
// The receive buffer length of the TCP socket
const int constexpr SOCKET_BUFFERLENGTH = 2048;
static volatile bool run = true;
static std::unique_ptr<QRWidget> qrWidget = nullptr;
static void doorlock_update(const Clientmessage &msg)
{
// TODO develop small X application to show the QR code
char buffer[1024];
snprintf(buffer, sizeof(buffer),
"qrencode -t ansi %s",
msg.token().c_str());
system(buffer);
if (qrWidget) {
qrWidget->setQRData(msg.token());
}
}
static int startGui(int argc, char** argv)
{
QApplication app(argc, argv);
app.setOrganizationName("Binary Kitchen");
app.setApplicationName("doorlock-client");
qrWidget = std::unique_ptr<QRWidget>(new QRWidget);
qrWidget->showFullScreen();
int retval = app.exec();
run = false;
return retval;
}
static int doorlock_client(const std::string &hostname,
const unsigned short port)
{
int retval = 0;
std::thread guiThread;
try {
tcp::resolver resolver(io_service);
@ -75,7 +96,11 @@ static int doorlock_client(const std::string &hostname,
if (!response)
throw std::runtime_error("Invalid response from server");
for (;;) {
guiThread = std::thread([] () {
startGui(0, nullptr);
});
for (;run;) {
length = socket.read_some(boost::asio::buffer(data), error);
if (error)
throw boost::system::system_error(error);
@ -94,6 +119,9 @@ static int doorlock_client(const std::string &hostname,
}
out:
if (guiThread.joinable()) {
guiThread.join();
}
return retval;
}
@ -137,7 +165,8 @@ int main(int argc, char** argv)
}
l(LogLevel::notice, "Starting doorlock-client");
retval = doorlock_client(hostname, port);
doorlock_client(hostname, port);
out:
l(LogLevel::notice, "Stopping doorlock-client");

View File

@ -0,0 +1,63 @@
#include <exception>
#include <memory>
#include <QPainter>
#include <QDebug>
#include <qrencode.h>
#include "qrwidget.h"
QRWidget::QRWidget(QWidget* parent) :
QWidget(parent),
_data(" ")
{
}
void QRWidget::setQRData(const std::string &data)
{
_data = QString::fromStdString(data);
update();
}
void QRWidget::paintEvent(QPaintEvent*)
{
QPainter painter(this);
std::unique_ptr<QRcode, void(*)(QRcode*)> qr(
QRcode_encodeString(_data.toStdString().c_str(), 1, QR_ECLEVEL_L, QR_MODE_8, 0),
[] (QRcode* ptr) {
if (ptr)
QRcode_free(ptr);
});
if (!qr)
throw std::runtime_error("Error generating QR Code");
QColor fg("black");
QColor bg("white");
painter.setBrush(bg);
painter.setPen(Qt::NoPen);
painter.drawRect(0,0,width(),height());
painter.setBrush(fg);
const int s=qr->width>0?qr->width:1;
const double w=width();
const double h=height();
const double aspect=w/h;
const double scale=((aspect>1.0)?h:w)/s;
for(int y=0;y<s;y++) {
const int yy=y*s;
for(int x=0;x<s;x++) {
const int xx=yy+x;
const unsigned char b=qr->data[xx];
if(b &0x01) {
const double rx1=x*scale, ry1=y*scale;
QRectF r(rx1, ry1, scale, scale);
painter.drawRects(&r,1);
}
}
}
}

21
doorlockd/src/qrwidget.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef QRWIDGET_H
#define QRWIDGET_H
#include <QWidget>
class QRWidget : public QWidget
{
Q_OBJECT
public:
explicit QRWidget(QWidget *parent = nullptr);
void setQRData(const std::string &data);
private:
QString _data;
protected:
void paintEvent(QPaintEvent *);
};
#endif