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:
parent
aa786b427a
commit
7ad6ad2731
46
core.cpp
46
core.cpp
|
@ -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
4
core.h
|
@ -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);
|
||||
|
|
|
@ -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"/>
|
||||
|
|
3
qtox.pro
3
qtox.pro
|
@ -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 \
|
||||
|
|
15
settings.cpp
15
settings.cpp
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
22
widget/tool/clickablelabel.h
Normal file
22
widget/tool/clickablelabel.h
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user