Commit ae95e721 authored by Ming Rui Zhang's avatar Ming Rui Zhang Committed by Sébastien Blin

qml: add user profile page

Change-Id: If2404505a4b8d45b3d3498ff71b8dbfbebe928c3
parent f86db31f
......@@ -171,7 +171,9 @@ HEADERS += ./src/aboutdialog.h \
./src/widgethelpers.h \
./src/recordwidget.h \
./src/networkmanager.h \
./src/connectivitymonitor.h
./src/connectivitymonitor.h \
./src/userprofile.h \
./src/qmlclipboardadapter.h
SOURCES += ./src/aboutdialog.cpp \
./src/banneditemwidget.cpp \
./src/conversationsfilterwidget.cpp \
......@@ -237,7 +239,8 @@ SOURCES += ./src/aboutdialog.cpp \
./src/widgethelpers.cpp \
./src/recordwidget.cpp \
./src/networkmanager.cpp \
./src/connectivitymonitor.cpp
./src/connectivitymonitor.cpp \
./src/userprofile.cpp
FORMS += ./src/aboutdialog.ui \
./src/advancedsipsettingwidget.ui \
./src/callwidget.ui \
......
......@@ -2,5 +2,6 @@
<qresource prefix="/">
<file>src/KeyBoardShortcutTable.qml</file>
<file>src/KeyBoardShortcutKey.qml</file>
<file>src/UserProfileCard.qml</file>
</qresource>
</RCC>
This diff is collapsed.
......@@ -40,6 +40,7 @@
#include "ringthemeutils.h"
#include "settingskey.h"
#include "aboutdialog.h"
#include "userprofile.h"
#include "globalinstances.h"
......@@ -415,14 +416,13 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos)
// separator
menu.addSeparator();
// copy number(infohash)
auto copyNumberAction = new QAction(tr("Copy number"), this);
menu.addAction(copyNumberAction);
connect(copyNumberAction, &QAction::triggered,
[contact]() {
QApplication::clipboard()->setText(
QString::fromStdString(contact.profileInfo.uri)
);
// show user profile
auto profileShowingAction = new QAction(tr("Profile"), this);
menu.addAction(profileShowingAction);
connect(profileShowingAction, &QAction::triggered,
[conversation, this]() {
UserProfile userProfile(conversation, qobject_cast<MainWindow*>(this->parent()->parent()->parent()));
userProfile.getContainer()->exec();
});
}
smartListModel_->isContextMenuOpen = true;
......@@ -430,45 +430,6 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos)
smartListModel_->isContextMenuOpen = false;
}
void
CallWidget::setupQRCode(QString ringID)
{
auto rcode = QRcode_encodeString(ringID.toStdString().c_str(),
0, //Let the version be decided by libqrencode
QR_ECLEVEL_L, // Lowest level of error correction
QR_MODE_8, // 8-bit data mode
1);
if (not rcode) {
qWarning() << "Failed to generate QR code: " << strerror(errno);
return;
}
auto margin = 5;
int qrwidth = rcode->width + margin * 2;
QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono);
QPainter painter;
painter.begin(&result);
painter.setClipRect(QRect(0, 0, qrwidth, qrwidth));
painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
painter.setBrush(Qt::black);
painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white);
unsigned char* p;
p = rcode->data;
for(int y = 0; y < rcode->width; y++) {
unsigned char* row = (p + (y * rcode->width));
for(int x = 0; x < rcode->width; x++) {
if(*(row + x) & 0x1) {
painter.drawRect(margin + x, margin + y, 1, 1);
}
}
}
painter.end();
QRcode_free(rcode);
ui->qrLabel->setPixmap(QPixmap::fromImage(result.scaled(QSize(qrSize_, qrSize_),
Qt::KeepAspectRatio)));
}
void
CallWidget::on_smartList_clicked(const QModelIndex& index)
{
......@@ -864,7 +825,8 @@ CallWidget::setSelectedAccount(const std::string& accountId)
auto isRingAccount = accountInfo.profileInfo.type == lrc::api::profile::Type::RING;
if (isRingAccount) {
ui->ringIdLabel->setText(QString::fromStdString(id));
setupQRCode(QString::fromStdString(accountInfo.profileInfo.uri));
ui->qrLabel->setPixmap(QPixmap::fromImage(Utils::setupQRCode(QString::fromStdString(accountInfo.profileInfo.uri), 5).scaled(QSize(qrSize_, qrSize_),
Qt::KeepAspectRatio)));
}
updateSmartList();
......
......@@ -110,7 +110,6 @@ private:
void conversationsButtonClicked();
void invitationsButtonClicked();
void setupSmartListContextMenu(const QPoint &pos);
void setupQRCode(QString ringID);
void backToWelcomePage();
void selectConversation(const QModelIndex& index);
......
......@@ -28,6 +28,7 @@
#include "utils.h"
#include "splashscreen.h"
#include "aboutdialog.h"
#include "qmlclipboardadapter.h"
#include <QApplication>
#include <QFile>
......@@ -296,9 +297,12 @@ main(int argc, char* argv[])
QObject::connect(&a, &QApplication::aboutToQuit, [&guard] { exitApp(guard); });
// for deployment only
// for deployment and register types
qmlRegisterType<QmlClipboardAdapter>("MyQClipboard", 1, 0, "QClipboard");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/src/KeyBoardShortcutTable.qml")));
engine.load(QUrl(QStringLiteral("qrc:/src/UserProfileCard.qml")));
auto ret = a.exec();
......
/***************************************************************************
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
//https://ruedigergad.com/2011/08/06/qml-and-clipboard-interaction/
#pragma once
#include <QApplication>
#include <QClipboard>
#include <QObject>
class QmlClipboardAdapter : public QObject
{
Q_OBJECT
public:
explicit QmlClipboardAdapter(QObject* parent = nullptr) : QObject(parent) {
clipboard_ = QApplication::clipboard();
}
Q_INVOKABLE void setText(QString text) {
clipboard_->setText(text, QClipboard::Clipboard);
}
private:
QClipboard* clipboard_;
};
/***************************************************************************
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
#include "userprofile.h"
UserProfile::UserProfile(lrc::api::conversation::Info convInfo, QWidget* parent) :
QmlPopupWidget(QUrl(QStringLiteral("")), parent)
{
// set image provider first, since when adding source, images are needed to be interpretted
engine()->addImageProvider(QLatin1String("userProfileImage"), new UserProfileImageProvider(convInfo));
setSource(QUrl(QStringLiteral("qrc:/src/UserProfileCard.qml")));
auto contact = LRCInstance::getCurrentAccountInfo().contactModel->getContact(convInfo.participants.at(0));
QString name = QString::fromStdString(contact.profileInfo.alias);
QString registeredName = QString::fromStdString(contact.registeredName);
QString uri = QString::fromStdString(contact.profileInfo.uri);
// force updating source, since image provide will only be requested once with the same source
QString userImageSource = "image://userProfileImage/user_";
userImageSource = userImageSource.append(name.isEmpty() ? registeredName : name).append(".png");
QString userQrImageSource = "image://userProfileImage/";
userQrImageSource = userQrImageSource.append(name.isEmpty() ? registeredName : name).append("_qr.png");
// setProperty keeps the binding, QQmlProperty().write() removes the binding
rootObject()->setProperty("userImageSource", userImageSource);
rootObject()->setProperty("qrImageSource", userQrImageSource);
rootObject()->setProperty("userNameText", registeredName.isEmpty() ? name : registeredName);
rootObject()->setProperty("registeredNameText", registeredName.isEmpty() ? "(None)" : registeredName);
rootObject()->setProperty("uriText", uri);
// widget setup
setMouseTracking(true);
setWindowFlags(Qt::Widget | Qt::FramelessWindowHint);
setClearColor(Qt::transparent);
setAttribute(Qt::WA_AlwaysStackOnTop);
setMinimumWidth(rootObject()->property("minWidth").toInt());
setMinimumHeight(rootObject()->property("minHeight").toInt());
}
UserProfile::~UserProfile()
{
engine()->removeImageProvider(QLatin1String("userProfileImage"));
}
/***************************************************************************
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
#pragma once
#include "widgethelpers.h"
#include "lrcinstance.h"
#include "utils.h"
#include <QQuickImageProvider>
class UserProfile : public QmlPopupWidget
{
Q_OBJECT
public:
explicit UserProfile(lrc::api::conversation::Info convInfo, QWidget* parent = nullptr);
~UserProfile();
};
class UserProfileImageProvider : public QObject, public QQuickImageProvider
{
private:
lrc::api::conversation::Info convInfo_;
public:
UserProfileImageProvider(lrc::api::conversation::Info convInfo) :
QQuickImageProvider(QQuickImageProvider::Image)
{
convInfo_ = convInfo;
}
QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) override
{
Q_UNUSED(size);
Q_UNUSED(requestedSize);
QSize scaleSize;
QImage image;
if (id.right(7) == "_qr.png") {
int width = 200;
int height = 200;
scaleSize = QSize(width, height);
auto contact = LRCInstance::getCurrentAccountInfo().contactModel->getContact(convInfo_.participants.at(0));
image = Utils::setupQRCode(QString::fromStdString(contact.profileInfo.uri), 0);
} else {
return Utils::conversationPhoto(convInfo_.uid, LRCInstance::getCurrentAccountInfo());
}
auto scaledImage = image.scaled(scaleSize, Qt::KeepAspectRatio);
return scaledImage;
}
};
\ No newline at end of file
......@@ -37,6 +37,7 @@
#include "version.h"
#include <globalinstances.h>
#include <qrencode.h>
//Qt
#include <QBitmap>
......@@ -713,6 +714,43 @@ Utils::pixmapFromSvg(const QString& svg_resource, const QSize& size)
return pixmap;
}
QImage
Utils::setupQRCode(QString ringID, int margin)
{
auto rcode = QRcode_encodeString(ringID.toStdString().c_str(),
0, //Let the version be decided by libqrencode
QR_ECLEVEL_L, // Lowest level of error correction
QR_MODE_8, // 8-bit data mode
1);
if (not rcode) {
qWarning() << "Failed to generate QR code: " << strerror(errno);
return QImage();
}
int qrwidth = rcode->width + margin * 2;
QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono);
QPainter painter;
painter.begin(&result);
painter.setClipRect(QRect(0, 0, qrwidth, qrwidth));
painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
painter.setBrush(Qt::black);
painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white);
unsigned char* p;
p = rcode->data;
for (int y = 0; y < rcode->width; y++) {
unsigned char* row = (p + (y * rcode->width));
for (int x = 0; x < rcode->width; x++) {
if (*(row + x) & 0x1) {
painter.drawRect(margin + x, margin + y, 1, 1);
}
}
}
painter.end();
QRcode_free(rcode);
return result;
}
QString
Utils::formattedTime(int duration)
{
......
......@@ -111,6 +111,7 @@ QImage scaleAndFrame(const QImage photo, const QSize& size = IMAGE_SIZE);
QImage accountPhoto(const lrc::api::account::Info& accountInfo, const QSize& size = IMAGE_SIZE);
QImage cropImage(const QImage& img);
QPixmap pixmapFromSvg(const QString& svg_resource, const QSize& size);
QImage setupQRCode(QString ringID, int margin);
// rounded corner
template<typename T>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment