1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Avatar support for ourselves

This commit is contained in:
Tux3 / Mlkj / !Lev.uXFMLA 2014-09-24 16:51:16 +02:00
parent aa786b427a
commit 7ad6ad2731
9 changed files with 154 additions and 5 deletions

View File

@ -35,6 +35,7 @@
#include <QCoreApplication>
#include <QDateTime>
#include <QList>
#include <QBuffer>
const QString Core::CONFIG_FILE_NAME = "data";
QList<ToxFile> Core::fileSendQueue;
@ -187,6 +188,8 @@ void Core::start()
tox_callback_file_send_request(tox, onFileSendRequestCallback, this);
tox_callback_file_control(tox, onFileControlCallback, this);
tox_callback_file_data(tox, onFileDataCallback, this);
tox_callback_avatar_info(tox, onAvatarInfoCallback, this);
tox_callback_avatar_data(tox, onAvatarDataCallback, this);
toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this);
toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this);
@ -205,9 +208,22 @@ void Core::start()
uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE];
tox_get_address(tox, friendAddress);
emit friendAddressGenerated(CFriendAddress::toString(friendAddress));
QPixmap pic = Settings::getInstance().getSavedAvatar();
if (!pic.isNull() && !pic.size().isEmpty())
{
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
pic.save(&buffer);
buffer.close();
tox_set_avatar(tox, TOX_AVATARFORMAT_PNG, (uint8_t*)data.constData(), data.size());
emit selfAvatarChanged(pic);
}
else
qDebug() << "Core: Error loading self avatar";
bootstrapDht();
toxTimer->start(tox_do_interval(tox));
@ -433,6 +449,18 @@ void Core::onFileDataCallback(Tox*, int32_t friendnumber, uint8_t filenumber, co
file->filesize, file->bytesSent, ToxFile::RECEIVING);
}
void Core::onAvatarInfoCallback(Tox* tox, int32_t friendnumber, uint8_t format,
uint8_t *hash, void *userdata)
{
qDebug() << "Core: Got avatar info from "<<friendnumber;
}
void Core::onAvatarDataCallback(Tox* tox, int32_t friendnumber, uint8_t format,
uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
{
qDebug() << "Core: Got avatar data from "<<friendnumber;
}
void Core::acceptFriendRequest(const QString& userId)
{
int friendId = tox_add_friend_norequest(tox, CUserId(userId).data());
@ -729,6 +757,22 @@ void Core::setUsername(const QString& username)
}
}
void Core::setAvatar(uint8_t format, const QByteArray& data)
{
if (tox_set_avatar(tox, format, (uint8_t*)data.constData(), data.size()) != 0)
{
qWarning() << "Core: Failed to set self avatar";
return;
}
else
qDebug() << "Core: Set avatar, format:"<<format<<", size:"<<data.size();
QPixmap pic;
pic.loadFromData(data);
Settings::getInstance().saveAvatar(pic);
emit selfAvatarChanged(pic);
}
ToxID Core::getSelfId()
{
uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE];

4
core.h
View File

@ -71,6 +71,7 @@ public slots:
void setStatus(Status status);
void setUsername(const QString& username);
void setStatusMessage(const QString& message);
void setAvatar(uint8_t format, const QByteArray& data);
void sendMessage(int friendId, const QString& message);
void sendGroupMessage(int groupId, const QString& message);
@ -123,6 +124,7 @@ signals:
void usernameSet(const QString& username);
void statusMessageSet(const QString& message);
void statusSet(Status status);
void selfAvatarChanged(const QPixmap& pic);
void messageSentResult(int friendId, const QString& message, int messageId);
void groupSentResult(int groupId, const QString& message, int result);
@ -182,6 +184,8 @@ private:
static void onFileControlCallback(Tox *tox, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber,
uint8_t control_type, const uint8_t *data, uint16_t length, void *core);
static void onFileDataCallback(Tox *tox, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *userdata);
static void onAvatarInfoCallback(Tox* tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata);
static void onAvatarDataCallback(Tox* tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata);
static void onAvInvite(void* toxav, int32_t call_index, void* core);
static void onAvStart(void* toxav, int32_t call_index, void* core);

View File

@ -1452,7 +1452,7 @@ QSplitter:handle{
<number>0</number>
</property>
<item>
<widget class="QLabel" name="profilePicture">
<widget class="ClickableLabel" name="profilePicture">
<property name="minimumSize">
<size>
<width>40</width>
@ -2093,7 +2093,7 @@ QSplitter:handle{
<x>0</x>
<y>0</y>
<width>263</width>
<height>373</height>
<height>378</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5"/>
@ -3228,7 +3228,7 @@ QSplitter:handle{
<x>0</x>
<y>0</y>
<width>716</width>
<height>23</height>
<height>19</height>
</rect>
</property>
</widget>
@ -3254,6 +3254,11 @@ QSplitter:handle{
<extends>QLabel</extends>
<header>widget/croppinglabel.h</header>
</customwidget>
<customwidget>
<class>ClickableLabel</class>
<extends>QLabel</extends>
<header>widget/tool/clickablelabel.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="res.qrc"/>

View File

@ -116,7 +116,8 @@ HEADERS += widget/form/addfriendform.h \
widget/settingsdialog.h \
widget/tool/chatactions/messageaction.h \
widget/tool/chatactions/filetransferaction.h \
widget/tool/chatactions/systemmessageaction.h
widget/tool/chatactions/systemmessageaction.h \
widget/tool/clickablelabel.h
SOURCES += \
widget/form/addfriendform.cpp \

View File

@ -27,6 +27,7 @@
#include <QList>
const QString Settings::FILENAME = "settings.ini";
const QString Settings::AVATAR_FILENAME = "avatar.dat";
bool Settings::makeToxPortable{false};
Settings::Settings() :
@ -257,6 +258,20 @@ QString Settings::getSettingsDirPath()
#endif
}
QPixmap Settings::getSavedAvatar()
{
QString filePath = QDir(getSettingsDirPath()).filePath(AVATAR_FILENAME);
QPixmap pic;
pic.load(filePath);
return pic;
}
void Settings::saveAvatar(QPixmap& pic)
{
QString filePath = QDir(getSettingsDirPath()).filePath(AVATAR_FILENAME);
pic.save(filePath, "png");
}
const QList<Settings::DhtServer>& Settings::getDhtServerList() const
{
return dhtServerList;

View File

@ -19,6 +19,7 @@
#include <QHash>
#include <QObject>
#include <QPixmap>
class Settings : public QObject
{
@ -57,6 +58,9 @@ public:
bool getEncryptLogs() const;
void setEncryptLogs(bool newValue);
QPixmap getSavedAvatar();
void saveAvatar(QPixmap& pic);
// Assume all widgets have unique names
// Don't use it to save every single thing you want to save, use it
// for some general purpose widgets, such as MainWindows or Splitters,
@ -138,6 +142,7 @@ private:
Settings& operator=(const Settings&) = delete;
static const QString FILENAME;
static const QString AVATAR_FILENAME;
bool loaded;

View File

@ -0,0 +1,22 @@
#ifndef CLICKABLELABEL_H
#define CLICKABLELABEL_H
#include <QLabel>
class QMouseEvent;
class QWidget;
class ClickableLabel : public QLabel
{
Q_OBJECT
public:
explicit ClickableLabel(QWidget* parent = 0) : QLabel(parent) {}
signals:
void clicked();
protected:
void mousePressEvent (QMouseEvent*) {emit clicked();}
};
#endif // CLICKABLELABEL_H

View File

@ -36,10 +36,12 @@
#include <QDebug>
#include <QFile>
#include <QString>
#include <QBuffer>
#include <QPainter>
#include <QMouseEvent>
#include <QClipboard>
#include <QThread>
#include <QFileDialog>
#include <tox/tox.h>
Widget *Widget::instance{nullptr};
@ -180,6 +182,7 @@ Widget::Widget(QWidget *parent)
connect(core, &Core::statusSet, this, &Widget::onStatusSet);
connect(core, &Core::usernameSet, this, &Widget::setUsername);
connect(core, &Core::statusMessageSet, this, &Widget::setStatusMessage);
connect(core, &Core::selfAvatarChanged, this, &Widget::onSelfAvatarLoaded);
connect(core, SIGNAL(fileDownloadFinished(const QString&)), &filesForm, SLOT(onFileDownloadComplete(const QString&)));
connect(core, SIGNAL(fileUploadFinished(const QString&)), &filesForm, SLOT(onFileUploadComplete(const QString&)));
connect(core, &Core::friendAdded, this, &Widget::addFriend);
@ -210,6 +213,7 @@ Widget::Widget(QWidget *parent)
connect(ui->settingsButton, SIGNAL(clicked()), this, SLOT(onSettingsClicked()));
connect(ui->nameLabel, SIGNAL(textChanged(QString,QString)), this, SLOT(onUsernameChanged(QString,QString)));
connect(ui->statusLabel, SIGNAL(textChanged(QString,QString)), this, SLOT(onStatusMessageChanged(QString,QString)));
connect(ui->profilePicture, SIGNAL(clicked()), this, SLOT(onAvatarClicked()));
connect(setStatusOnline, SIGNAL(triggered()), this, SLOT(setStatusOnline()));
connect(setStatusAway, SIGNAL(triggered()), this, SLOT(setStatusAway()));
connect(setStatusBusy, SIGNAL(triggered()), this, SLOT(setStatusBusy()));
@ -271,6 +275,53 @@ Camera* Widget::getCamera()
return camera;
}
void Widget::onAvatarClicked()
{
QString filename = QFileDialog::getOpenFileName(this, "Choose a profile picture");
QFile file(filename);
file.open(QIODevice::ReadOnly);
if (!file.isOpen())
{
QMessageBox::critical(this, "Error", "Unable to open this file");
return;
}
QPixmap pic;
if (!pic.loadFromData(file.readAll()))
{
QMessageBox::critical(this, "Error", "Unable to read this image");
return;
}
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
pic.save(&buffer, "PNG");
buffer.close();
if (bytes.size() >= TOX_MAX_AVATAR_DATA_LENGTH)
{
pic = pic.scaledToWidth(64, Qt::SmoothTransformation);
bytes.clear();
buffer.open(QIODevice::WriteOnly);
pic.save(&buffer, "PNG");
buffer.close();
}
if (bytes.size() >= TOX_MAX_AVATAR_DATA_LENGTH)
{
QMessageBox::critical(this, "Error", "This image is too big");
return;
}
core->setAvatar(TOX_AVATARFORMAT_PNG, bytes);
}
void Widget::onSelfAvatarLoaded(const QPixmap& pic)
{
ui->profilePicture->setPixmap(pic);
}
void Widget::onConnected()
{
ui->statusButton->setEnabled(true);

View File

@ -80,6 +80,8 @@ private slots:
void onTransferClicked();
void onSettingsClicked();
void onFailedToStartCore();
void onAvatarClicked();
void onSelfAvatarLoaded(const QPixmap &pic);
void onUsernameChanged(const QString& newUsername, const QString& oldUsername);
void onStatusMessageChanged(const QString& newStatusMessage, const QString& oldStatusMessage);
void setUsername(const QString& username);