mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Merge branch 'pr1351'
This commit is contained in:
commit
01a4cdd07e
12
INSTALL.md
12
INSTALL.md
|
@ -15,7 +15,7 @@
|
|||
| OpenCV | >= 2.4.9 | core, highgui, imgproc |
|
||||
| OpenAL Soft | >= 1.16.0 | |
|
||||
| filter_audio | most recent | |
|
||||
|
||||
| qrencode | >= 3.0.3 | |
|
||||
|
||||
<a name="linux" />
|
||||
##Linux
|
||||
|
@ -59,22 +59,22 @@ git clone https://github.com/tux3/qTox.git qTox
|
|||
|
||||
The following steps assumes that you cloned the repository at "/home/user/qTox". If you decided to choose another location, replace corresponding parts.
|
||||
|
||||
###GCC, Qt, OpenCV and OpanAL Soft
|
||||
###GCC, Qt, OpenCV, OpanAL Soft and QRCode
|
||||
|
||||
Arch Linux:
|
||||
```bash
|
||||
sudo pacman -S --needed base-devel qt5 opencv openal libxss
|
||||
sudo pacman -S --needed base-devel qt5 opencv openal libxss qrencode
|
||||
```
|
||||
|
||||
Debian / Ubuntu:
|
||||
```bash
|
||||
sudo apt-get install build-essential qt5-qmake qt5-default qttools5-dev-tools libqt5opengl5-dev libqt5svg5-dev libopenal-dev libopencv-dev libxss-dev
|
||||
sudo apt-get install build-essential qt5-qmake qt5-default qttools5-dev-tools libqt5opengl5-dev libqt5svg5-dev libopenal-dev libopencv-dev libxss-dev qrencode
|
||||
```
|
||||
|
||||
Fedora:
|
||||
```bash
|
||||
yum groupinstall "Development Tools"
|
||||
yum install qt-devel qt-doc qt-creator qt5-qtsvg opencv-devel openal-soft-devel libXScrnSaver-devel
|
||||
yum install qt-devel qt-doc qt-creator qt5-qtsvg opencv-devel openal-soft-devel libXScrnSaver-devel qrencode
|
||||
```
|
||||
|
||||
Slackware:
|
||||
|
@ -87,6 +87,8 @@ http://slackbuilds.org/repository/14.1/libraries/qt5/
|
|||
|
||||
http://slackbuilds.org/repository/14.1/libraries/opencv/
|
||||
|
||||
http://slackbuilds.org/slackbuilds/14.1/graphics/qrencode/
|
||||
|
||||
|
||||
###Tox Core
|
||||
|
||||
|
|
11
qtox.pro
11
qtox.pro
|
@ -134,7 +134,7 @@ win32 {
|
|||
LIBS += -L$$PWD/libs/lib -ltoxav -ltoxcore -ltoxencryptsave -ltoxdns -lsodium -lvpx -lpthread
|
||||
LIBS += -L$$PWD/libs/lib -lopencv_core249 -lopencv_highgui249 -lopencv_imgproc249 -lOpenAL32 -lopus
|
||||
LIBS += -lopengl32 -lole32 -loleaut32 -luuid -lvfw32 -lws2_32 -liphlpapi -lz
|
||||
|
||||
LIBS += -lqrencode
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
contains(STATICPKG, YES) {
|
||||
LIBS += -Wl,-Bstatic -lfilteraudio
|
||||
|
@ -149,6 +149,7 @@ win32 {
|
|||
QMAKE_INFO_PLIST = osx/info.plist
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
|
||||
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lvpx -lopus -framework OpenAL -lopencv_core -lopencv_highgui -mmacosx-version-min=10.7
|
||||
LIBS += -lqrencode
|
||||
contains(DEFINES, QTOX_PLATFORM_EXT) { LIBS += -framework IOKit -framework CoreFoundation }
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) { LIBS += -lfilteraudio }
|
||||
} else {
|
||||
|
@ -165,8 +166,10 @@ win32 {
|
|||
LIBS += -L$$PWD/libs/lib/ -lopus -lvpx -lopenal -Wl,-Bstatic -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lopencv_highgui -lopencv_imgproc -lopencv_core -lz -Wl,-Bdynamic
|
||||
LIBS += -Wl,-Bstatic -ljpeg -ltiff -lpng -ljasper -lIlmImf -lIlmThread -lIex -ldc1394 -lraw1394 -lHalf -lz -llzma -ljbig
|
||||
LIBS += -Wl,-Bdynamic -lv4l1 -lv4l2 -lavformat -lavcodec -lavutil -lswscale -lusb-1.0
|
||||
LIBS += -lqrencode
|
||||
} else {
|
||||
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lvpx -lsodium -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc
|
||||
LIBS += -lqrencode
|
||||
}
|
||||
|
||||
contains(DEFINES, QTOX_PLATFORM_EXT) {
|
||||
|
@ -424,7 +427,8 @@ SOURCES += \
|
|||
src/video/netvideosource.cpp \
|
||||
src/video/videoframe.cpp \
|
||||
src/widget/gui.cpp \
|
||||
src/toxme.cpp
|
||||
src/toxme.cpp \
|
||||
src/misc/qrwidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/audio.h \
|
||||
|
@ -445,4 +449,5 @@ HEADERS += \
|
|||
src/video/videoframe.h \
|
||||
src/video/videosource.h \
|
||||
src/widget/gui.h \
|
||||
src/toxme.h
|
||||
src/toxme.h \
|
||||
src/misc/qrwidget.h
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
if which apt-get; then
|
||||
sudo apt-get install build-essential qt5-qmake qt5-default libopenal-dev libopencv-dev \
|
||||
libtool autotools-dev automake checkinstall check libopus-dev libvpx-dev qttools5-dev-tools qtchooser libxss-dev libqt5svg5*
|
||||
libtool autotools-dev automake checkinstall check libopus-dev libvpx-dev qttools5-dev-tools qtchooser libxss-dev libqt5svg5* qrencode
|
||||
elif which pacman; then
|
||||
sudo pacman -S --needed base-devel qt5 opencv openal opus libvpx libxss qt5-svg
|
||||
sudo pacman -S --needed base-devel qt5 opencv openal opus libvpx libxss qt5-svg qrencode
|
||||
elif which yum; then
|
||||
sudo yum groupinstall "Development Tools"
|
||||
sudo yum install qt-devel qt-doc qt-creator opencv-devel openal-soft-devel libtool autoconf automake check check-devel libXScrnSaver-devel qt5-qtsvg
|
||||
sudo yum install qt-devel qt-doc qt-creator opencv-devel openal-soft-devel libtool autoconf automake check check-devel libXScrnSaver-devel qt5-qtsvg qrencode
|
||||
else
|
||||
echo "Unknown package manager, attempting to compile anyways"
|
||||
fi
|
||||
|
|
103
src/misc/qrwidget.cpp
Normal file
103
src/misc/qrwidget.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include "qrwidget.h"
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
#include <QBuffer>
|
||||
#include <QImage>
|
||||
#include "qrencode.h"
|
||||
|
||||
QRWidget::QRWidget(QWidget *parent) : QWidget(parent), data("0")
|
||||
//Note: The encoding fails with empty string so I just default to something else.
|
||||
//Use the setQRData() call to change this.
|
||||
{
|
||||
//size of the qimage might be problematic in the future, but it works for me
|
||||
size.setWidth(480);
|
||||
size.setHeight(480);
|
||||
image = new QImage(size, QImage::Format_RGB32);
|
||||
}
|
||||
|
||||
void QRWidget::setQRData(QString data)
|
||||
{
|
||||
this->data = "tox:" + data;
|
||||
paintImage();
|
||||
}
|
||||
|
||||
QImage* QRWidget::getImage()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QRWidget::saveImage
|
||||
* @param path Full path to the file with extension.
|
||||
* @return indicate if saving was successful.
|
||||
*/
|
||||
bool QRWidget::saveImage(QString path)
|
||||
{
|
||||
return image->save(path, 0, 75); //0 - image format same as file extension, 75-quality, png file is ~6.3kb
|
||||
}
|
||||
|
||||
QString QRWidget::getImageAsText()
|
||||
{
|
||||
paintImage();
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image->save(&buffer, "PNG"); // writes the image in PNG format inside the buffer
|
||||
|
||||
QString iconBase64 = QString::fromLatin1(ba.toBase64().data());
|
||||
QString base64Image = "<img width=\"300\" heigth=\"300\" src=\"data:image/png;base64," + iconBase64 +"\" />";
|
||||
|
||||
return QString(base64Image);
|
||||
}
|
||||
|
||||
//http://stackoverflow.com/questions/21400254/how-to-draw-a-qr-code-with-qt-in-native-c-c
|
||||
void QRWidget::paintImage()
|
||||
{
|
||||
QPainter painter(image);
|
||||
//NOTE: I have hardcoded some parameters here that would make more sense as variables.
|
||||
// ECLEVEL_M is much faster recognizable by barcodescanner any any other type
|
||||
QRcode *qr = QRcode_encodeString(data.toStdString().c_str(), 1, QR_ECLEVEL_M, QR_MODE_8, 0);
|
||||
|
||||
if(0 != qr)
|
||||
{
|
||||
QColor fg("black");
|
||||
QColor bg("white");
|
||||
painter.setBrush(bg);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRect(0, 0, size.width(), size.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
QRcode_free(qr);
|
||||
painter.save();
|
||||
}
|
||||
else
|
||||
{
|
||||
QColor error("red");
|
||||
painter.setBrush(error);
|
||||
painter.drawRect(0, 0, width(), height());
|
||||
qDebug() << "QR FAIL: " << strerror(errno);
|
||||
}
|
||||
|
||||
qr = 0;
|
||||
}
|
26
src/misc/qrwidget.h
Normal file
26
src/misc/qrwidget.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef QRWIDGET_H
|
||||
#define QRWIDGET_H
|
||||
|
||||
// https://stackoverflow.com/questions/21400254/how-to-draw-a-qr-code-with-qt-in-native-c-c
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QRWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QRWidget(QWidget *parent = 0);
|
||||
void setQRData(QString data);
|
||||
QString getImageAsText();
|
||||
QImage* getImage();
|
||||
bool saveImage(QString path);
|
||||
|
||||
private:
|
||||
QString data;
|
||||
void paintImage();
|
||||
QImage *image;
|
||||
QSize size;
|
||||
};
|
||||
|
||||
#endif // QRWIDGET_H
|
|
@ -36,7 +36,6 @@
|
|||
#include <QFileDialog>
|
||||
#include <QBuffer>
|
||||
|
||||
|
||||
void ProfileForm::refreshProfiles()
|
||||
{
|
||||
bodyUI->profiles->clear();
|
||||
|
@ -76,9 +75,11 @@ ProfileForm::ProfileForm(QWidget *parent) :
|
|||
toxId->setReadOnly(true);
|
||||
toxId->setFrame(false);
|
||||
toxId->setFont(Style::getFont(Style::Small));
|
||||
|
||||
QVBoxLayout *toxIdGroup = qobject_cast<QVBoxLayout*>(bodyUI->toxGroup->layout());
|
||||
toxIdGroup->replaceWidget(bodyUI->toxId, toxId);
|
||||
bodyUI->toxId->hide();
|
||||
|
||||
bodyUI->toxGroup->layout()->addWidget(toxId);
|
||||
|
||||
profilePicture = new MaskablePixmapWidget(this, QSize(64, 64), ":/img/avatar_mask.png");
|
||||
profilePicture->setPixmap(QPixmap(":/img/contact_dark.png"));
|
||||
profilePicture->setClickable(true);
|
||||
|
@ -169,6 +170,11 @@ void ProfileForm::setToxId(const QString& id)
|
|||
{
|
||||
toxId->setText(id);
|
||||
toxId->setCursorPosition(0);
|
||||
|
||||
qr = new QRWidget();
|
||||
qr->setQRData(id);
|
||||
bodyUI->qrCode->setPixmap(QPixmap::fromImage(qr->getImage()->scaledToWidth(150)));
|
||||
bodyUI->qrCode->setToolTip(qr->getImageAsText());
|
||||
}
|
||||
|
||||
void ProfileForm::onAvatarClicked()
|
||||
|
@ -369,3 +375,32 @@ void ProfileForm::showEvent(QShowEvent *event)
|
|||
refreshProfiles();
|
||||
QWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void ProfileForm::on_copyQr_clicked()
|
||||
{
|
||||
QApplication::clipboard()->setImage(*qr->getImage());
|
||||
}
|
||||
|
||||
void ProfileForm::on_saveQr_clicked()
|
||||
{
|
||||
QString current = bodyUI->profiles->currentText() + ".png";
|
||||
QString path = QFileDialog::getSaveFileName(0, tr("Save", "save qr image"),
|
||||
QDir::home().filePath(current),
|
||||
tr("Save QrCode (*.png)", "save dialog filter"));
|
||||
if (!path.isEmpty())
|
||||
{
|
||||
bool success;
|
||||
if (QFile::exists(path))
|
||||
{
|
||||
success = QFile::remove(path);
|
||||
if (!success)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Failed to remove file"), tr("The file you chose to overwrite could not be removed first."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
success = qr->saveImage(path);
|
||||
if (!success)
|
||||
QMessageBox::warning(this, tr("Failed to copy file"), tr("The file you chose could not be written to."));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include "src/core.h"
|
||||
#include "src/misc/qrwidget.h"
|
||||
|
||||
class CroppingLabel;
|
||||
class Core;
|
||||
|
@ -36,7 +37,7 @@ class ClickableTE : public QLineEdit
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
protected:
|
||||
|
@ -73,7 +74,10 @@ private slots:
|
|||
void onNewClicked();
|
||||
void disableSwitching();
|
||||
void enableSwitching();
|
||||
|
||||
void on_copyQr_clicked();
|
||||
|
||||
void on_saveQr_clicked();
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent *);
|
||||
|
||||
|
@ -85,6 +89,7 @@ private:
|
|||
Core* core;
|
||||
QTimer timer;
|
||||
bool hasCheck = false;
|
||||
QRWidget *qr;
|
||||
|
||||
ClickableTE* toxId;
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>439</width>
|
||||
<height>472</height>
|
||||
<width>442</width>
|
||||
<height>659</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -39,8 +39,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>419</width>
|
||||
<height>452</height>
|
||||
<width>422</width>
|
||||
<height>639</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,1">
|
||||
|
@ -97,6 +97,52 @@ Share it with your friends to communicate.</string>
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="toxId"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="verticalFrame">
|
||||
<layout class="QHBoxLayout" name="qrGroup">
|
||||
<item>
|
||||
<widget class="QLabel" name="qrCode">
|
||||
<property name="text">
|
||||
<string>QRCODE</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="horizontalFrame">
|
||||
<layout class="QVBoxLayout" name="qrButtons">
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Share this code, so friends can add you</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignVCenter">
|
||||
<widget class="QPushButton" name="saveQr">
|
||||
<property name="text">
|
||||
<string>Save image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignVCenter">
|
||||
<widget class="QPushButton" name="copyQr">
|
||||
<property name="text">
|
||||
<string>Copy image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -212,7 +258,7 @@ Profile does not contain your history.</string>
|
|||
<customwidget>
|
||||
<class>CroppingLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>src/widget/croppinglabel.h</header>
|
||||
<header location="global">src/widget/croppinglabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
|
Loading…
Reference in New Issue
Block a user