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

refactor(id): make ContactId interface, implement GroupId

Precursor for group history, friend blocking
This commit is contained in:
Anthony Bilinski 2019-04-11 13:38:37 -07:00
parent 229ca307cf
commit 97d05f9d67
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
27 changed files with 374 additions and 183 deletions

View File

@ -288,12 +288,16 @@ set(${PROJECT_NAME}_SOURCES
src/core/toxfilepause.h
src/core/toxid.cpp
src/core/toxid.h
src/core/groupid.cpp
src/core/groupid.h
src/core/toxlogger.cpp
src/core/toxlogger.h
src/core/toxoptions.cpp
src/core/toxoptions.h
src/core/toxpk.cpp
src/core/toxpk.h
src/core/contactid.cpp
src/core/contactid.h
src/core/toxstring.cpp
src/core/toxstring.h
src/friendlist.cpp

View File

@ -19,7 +19,7 @@ function(auto_test subsystem module)
endfunction()
auto_test(core core)
auto_test(core toxpk)
auto_test(core contactid)
auto_test(core toxid)
auto_test(core toxstring)
auto_test(chatlog textformatter)

93
src/core/contactid.cpp Normal file
View File

@ -0,0 +1,93 @@
#include <QByteArray>
#include <QString>
#include <cstdint>
#include <QHash>
#include "src/core/contactid.h"
/**
* @brief The default constructor. Creates an empty id.
*/
ContactId::ContactId()
: id()
{
}
/**
* @brief Constructs a ContactId from bytes.
* @param rawId The bytes to construct the ContactId from.
*/
ContactId::ContactId(const QByteArray& rawId)
{
id = QByteArray(rawId);
}
/**
* @brief Compares the equality of the ContactId.
* @param other ContactId to compare.
* @return True if both ContactId are equal, false otherwise.
*/
bool ContactId::operator==(const ContactId& other) const
{
return id == other.id;
}
/**
* @brief Compares the inequality of the ContactId.
* @param other ContactId to compare.
* @return True if both ContactIds are not equal, false otherwise.
*/
bool ContactId::operator!=(const ContactId& other) const
{
return id != other.id;
}
/**
* @brief Compares two ContactIds
* @param other ContactId to compare.
* @return True if this ContactIds is less than the other ContactId, false otherwise.
*/
bool ContactId::operator<(const ContactId& other) const
{
return id < other.id;
}
/**
* @brief Converts the ContactId to a uppercase hex string.
* @return QString containing the hex representation of the id
*/
QString ContactId::toString() const
{
return id.toHex().toUpper();
}
/**
* @brief Returns a pointer to the raw id data.
* @return Pointer to the raw id data, which is exactly `ContactId::getPkSize()`
* bytes long. Returns a nullptr if the ContactId is empty.
*/
const uint8_t* ContactId::getData() const
{
if (id.isEmpty()) {
return nullptr;
}
return reinterpret_cast<const uint8_t*>(id.constData());
}
/**
* @brief Get a copy of the id
* @return Copied id bytes
*/
QByteArray ContactId::getByteArray() const
{
return QByteArray(id); // TODO: Is a copy really necessary?
}
/**
* @brief Checks if the ContactId contains a id.
* @return True if there is a id, False otherwise.
*/
bool ContactId::isEmpty() const
{
return id.isEmpty();
}

38
src/core/contactid.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef CONTACTID_H
#define CONTACTID_H
#include <QByteArray>
#include <QString>
#include <cstdint>
#include <QHash>
#include <memory>
class ContactId
{
public:
virtual ~ContactId() = default;
ContactId& operator=(const ContactId& other) = default;
ContactId& operator=(ContactId&& other) = default;
bool operator==(const ContactId& other) const;
bool operator!=(const ContactId& other) const;
bool operator<(const ContactId& other) const;
QString toString() const;
QByteArray getByteArray() const;
const uint8_t* getData() const;
bool isEmpty() const;
virtual int getSize() const = 0;
protected:
ContactId();
explicit ContactId(const QByteArray& rawId);
QByteArray id;
};
inline uint qHash(const std::shared_ptr<const ContactId> id)
{
return qHash(id->getByteArray());
}
using ContactIdPtr = std::shared_ptr<const ContactId>;
#endif // CONTACTID_H

View File

@ -455,7 +455,7 @@ void Core::bootstrapDht()
ToxPk pk = ToxId{dhtServer.userId}.getPublicKey();
const uint8_t* pkPtr = reinterpret_cast<const uint8_t*>(pk.getBytes());
const uint8_t* pkPtr = pk.getData();
if (!tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, nullptr)) {
qDebug() << "Error bootstrapping from " + dhtServer.name;
@ -599,7 +599,7 @@ void Core::acceptFriendRequest(const ToxPk& friendPk)
{
QMutexLocker ml{&coreLoopLock};
// TODO: error handling
uint32_t friendId = tox_friend_add_norequest(tox.get(), friendPk.getBytes(), nullptr);
uint32_t friendId = tox_friend_add_norequest(tox.get(), friendPk.getData(), nullptr);
if (friendId == std::numeric_limits<uint32_t>::max()) {
emit failedToAddFriend(friendPk);
} else {
@ -1027,17 +1027,18 @@ void Core::loadGroups()
for(size_t i = 0; i < groupCount; ++i) {
TOX_ERR_CONFERENCE_TITLE error;
size_t titleSize = tox_conference_get_title_size(tox.get(), groupIds[i], &error);
const auto groupId = static_cast<int>(groupIds[i]);
size_t titleSize = tox_conference_get_title_size(tox.get(), groupId, &error);
if (LogConferenceTitleError(error)) {
continue;
}
QByteArray name(titleSize, Qt::Uninitialized);
if (!tox_conference_get_title(tox.get(), groupIds[i], reinterpret_cast<uint8_t*>(name.data()), &error))
if (!tox_conference_get_title(tox.get(), groupId, reinterpret_cast<uint8_t*>(name.data()), &error))
if (LogConferenceTitleError(error)) {
continue;
}
emit emptyGroupCreated(static_cast<int>(groupIds[i]), ToxString(name).getQString());
emit emptyGroupCreated(groupId, getGroupPersistentId(groupId), ToxString(name).getQString());
}
delete[] groupIds;
@ -1095,6 +1096,19 @@ bool Core::parsePeerQueryError(Tox_Err_Conference_Peer_Query error) const
}
}
GroupId Core::getGroupPersistentId(uint32_t groupNumber) {
QMutexLocker ml{&coreLoopLock};
size_t conferenceIdSize = TOX_CONFERENCE_UID_SIZE;
QByteArray groupPersistentId(conferenceIdSize, Qt::Uninitialized);
if (tox_conference_get_id(tox.get(), groupNumber, reinterpret_cast<uint8_t*>(groupPersistentId.data()))) {
return GroupId{groupPersistentId};
} else {
qCritical() << "Failed to get conference ID of group" << groupNumber;
return {};
}
}
/**
* @brief Get number of peers in the conference.
* @return The number of peers in the conference. UINT32_MAX on failure.
@ -1323,7 +1337,7 @@ int Core::createGroup(uint8_t type)
switch (error) {
case TOX_ERR_CONFERENCE_NEW_OK:
emit emptyGroupCreated(groupId);
emit emptyGroupCreated(groupId, getGroupPersistentId(groupId));
return groupId;
case TOX_ERR_CONFERENCE_NEW_INIT:
@ -1335,7 +1349,7 @@ int Core::createGroup(uint8_t type)
}
} else if (type == TOX_CONFERENCE_TYPE_AV) {
uint32_t groupId = toxav_add_av_groupchat(tox.get(), CoreAV::groupCallCallback, this);
emit emptyGroupCreated(groupId);
emit emptyGroupCreated(groupId, getGroupPersistentId(groupId));
return groupId;
} else {
qWarning() << "createGroup: Unknown type " << type;
@ -1366,7 +1380,7 @@ bool Core::hasFriendWithPublicKey(const ToxPk& publicKey) const
}
// TODO: error handling
uint32_t friendId = tox_friend_by_public_key(tox.get(), publicKey.getBytes(), nullptr);
uint32_t friendId = tox_friend_by_public_key(tox.get(), publicKey.getData(), nullptr);
return friendId != std::numeric_limits<uint32_t>::max();
}
@ -1443,7 +1457,7 @@ QString Core::getPeerName(const ToxPk& id) const
QMutexLocker ml{&coreLoopLock};
QString name;
uint32_t friendId = tox_friend_by_public_key(tox.get(), id.getBytes(), nullptr);
uint32_t friendId = tox_friend_by_public_key(tox.get(), id.getData(), nullptr);
if (friendId == std::numeric_limits<uint32_t>::max()) {
qWarning() << "getPeerName: No such peer";
return name;

View File

@ -23,6 +23,8 @@
#include "toxfile.h"
#include "toxid.h"
#include "toxpk.h"
#include "groupid.h"
#include "src/util/strongtype.h"
#include <tox/tox.h>
@ -77,10 +79,9 @@ public:
static const QString TOX_EXT;
static QStringList splitMessage(const QString& message, int maxLen);
QString getPeerName(const ToxPk& id) const;
QVector<uint32_t> getFriendList() const;
GroupId getGroupPersistentId(uint32_t groupNumber);
uint32_t getGroupNumberPeers(int groupId) const;
QString getGroupPeerName(int groupId, int peerId) const;
ToxPk getGroupPeerPk(int groupId, int peerId) const;
@ -171,7 +172,7 @@ signals:
void friendRemoved(uint32_t friendId);
void friendLastSeenChanged(uint32_t friendId, const QDateTime& dateTime);
void emptyGroupCreated(int groupnumber, const QString& title = QString());
void emptyGroupCreated(int groupnumber, const GroupId groupId, const QString& title = QString());
void groupInviteReceived(const GroupInvite& inviteInfo);
void groupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction);
void groupNamelistChanged(int groupnumber, int peernumber, uint8_t change);

61
src/core/groupid.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "groupid.h"
#include <tox/tox.h>
#include <QByteArray>
#include <QString>
#include <cassert>
/**
* @class GroupId
* @brief This class represents a long term persistent group identifier.
*/
/**
* @brief The default constructor. Creates an empty Tox group ID.
*/
GroupId::GroupId()
: ContactId()
{
}
/**
* @brief The copy constructor.
* @param other GroupId to copy
*/
GroupId::GroupId(const GroupId& other)
: ContactId(other.id)
{
}
/**
* @brief Constructs a GroupId from bytes.
* @param rawId The bytes to construct the GroupId from. The lenght must be exactly
* TOX_CONFERENCE_UID_SIZE, else the GroupId will be empty.
*/
GroupId::GroupId(const QByteArray& rawId)
: ContactId([rawId](){
assert(rawId.length() == TOX_CONFERENCE_UID_SIZE);
return rawId;}())
{
}
/**
* @brief Constructs a GroupId from bytes.
* @param rawId The bytes to construct the GroupId from, will read exactly
* TOX_CONFERENCE_UID_SIZE from the specified buffer.
*/
GroupId::GroupId(const uint8_t* rawId)
: ContactId(QByteArray(reinterpret_cast<const char*>(rawId), TOX_CONFERENCE_UID_SIZE))
{
}
/**
* @brief Get size of public id in bytes.
* @return Size of public id in bytes.
*/
int GroupId::getSize() const
{
return TOX_CONFERENCE_UID_SIZE;
}

18
src/core/groupid.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef GROUPID_H
#define GROUPID_H
#include "src/core/contactid.h"
#include <QByteArray>
#include <cstdint>
class GroupId : public ContactId
{
public:
GroupId();
GroupId(const GroupId& other);
explicit GroupId(const QByteArray& rawId);
explicit GroupId(const uint8_t* rawId);
int getSize() const override;
};
#endif // GROUPID_H

View File

@ -193,7 +193,12 @@ const uint8_t* ToxId::getBytes() const
*/
ToxPk ToxId::getPublicKey() const
{
return ToxPk(toxId.left(TOX_PUBLIC_KEY_SIZE));
auto const pkBytes = toxId.left(TOX_PUBLIC_KEY_SIZE);
if (pkBytes.isEmpty()) {
return ToxPk{};
} else {
return ToxPk{pkBytes};
}
}
/**

View File

@ -5,6 +5,8 @@
#include <QByteArray>
#include <QString>
#include <cassert>
/**
* @class ToxPk
* @brief This class represents a Tox Public Key, which is a part of Tox ID.
@ -14,7 +16,7 @@
* @brief The default constructor. Creates an empty Tox key.
*/
ToxPk::ToxPk()
: key()
: ContactId()
{
}
@ -23,7 +25,7 @@ ToxPk::ToxPk()
* @param other ToxPk to copy
*/
ToxPk::ToxPk(const ToxPk& other)
: key(other.key)
: ContactId(other.id)
{
}
@ -33,12 +35,10 @@ ToxPk::ToxPk(const ToxPk& other)
* TOX_PUBLIC_KEY_SIZE, else the ToxPk will be empty.
*/
ToxPk::ToxPk(const QByteArray& rawId)
: ContactId([rawId](){
assert(rawId.length() == TOX_PUBLIC_KEY_SIZE);
return rawId;}())
{
if (rawId.length() == TOX_PUBLIC_KEY_SIZE) {
key = QByteArray(rawId);
} else {
key = QByteArray();
}
}
/**
@ -47,86 +47,15 @@ ToxPk::ToxPk(const QByteArray& rawId)
* TOX_PUBLIC_KEY_SIZE from the specified buffer.
*/
ToxPk::ToxPk(const uint8_t* rawId)
: ContactId(QByteArray(reinterpret_cast<const char*>(rawId), TOX_PUBLIC_KEY_SIZE))
{
key = QByteArray(reinterpret_cast<const char*>(rawId), TOX_PUBLIC_KEY_SIZE);
}
/**
* @brief Compares the equality of the ToxPk.
* @param other ToxPk to compare.
* @return True if both ToxPks are equal, false otherwise.
*/
bool ToxPk::operator==(const ToxPk& other) const
{
return key == other.key;
}
/**
* @brief Compares the inequality of the ToxPk.
* @param other ToxPk to compare.
* @return True if both ToxPks are not equal, false otherwise.
*/
bool ToxPk::operator!=(const ToxPk& other) const
{
return key != other.key;
}
/**
* @brief Compares two ToxPks
* @param other ToxPk to compare.
* @return True if this ToxPks is less than the other ToxPk, false otherwise.
*/
bool ToxPk::operator<(const ToxPk& other) const
{
return key < other.key;
}
/**
* @brief Converts the ToxPk to a uppercase hex string.
* @return QString containing the hex representation of the key
*/
QString ToxPk::toString() const
{
return key.toHex().toUpper();
}
/**
* @brief Returns a pointer to the raw key data.
* @return Pointer to the raw key data, which is exactly `ToxPk::getPkSize()`
* bytes long. Returns a nullptr if the ToxPk is empty.
*/
const uint8_t* ToxPk::getBytes() const
{
if (key.isEmpty()) {
return nullptr;
}
return reinterpret_cast<const uint8_t*>(key.constData());
}
/**
* @brief Get a copy of the key
* @return Copied key bytes
*/
QByteArray ToxPk::getKey() const
{
return QByteArray(key); // TODO: Is a copy really necessary?
}
/**
* @brief Checks if the ToxPk contains a key.
* @return True if there is a key, False otherwise.
*/
bool ToxPk::isEmpty() const
{
return key.isEmpty();
}
/**
* @brief Get size of public key in bytes.
* @return Size of public key in bytes.
*/
int ToxPk::getPkSize()
int ToxPk::getSize() const
{
return TOX_PUBLIC_KEY_SIZE;
}

View File

@ -1,32 +1,18 @@
#ifndef TOXPK_H
#define TOXPK_H
#include "src/core/contactid.h"
#include <QByteArray>
#include <QString>
#include <cstdint>
class ToxPk
class ToxPk : public ContactId
{
public:
ToxPk();
ToxPk(const ToxPk& other);
explicit ToxPk(const QByteArray& rawId);
explicit ToxPk(const uint8_t* rawId);
ToxPk& operator=(const ToxPk& other) = default;
ToxPk& operator=(ToxPk&& other) = default;
bool operator==(const ToxPk& other) const;
bool operator!=(const ToxPk& other) const;
bool operator<(const ToxPk& other) const;
QString toString() const;
QByteArray getKey() const;
const uint8_t* getBytes() const;
bool isEmpty() const;
static int getPkSize();
private:
QByteArray key;
int getSize() const override;
};
#endif // TOXPK_H

View File

@ -37,7 +37,7 @@ Friend* FriendList::addFriend(uint32_t friendId, const ToxPk& friendPk)
QString alias = Settings::getInstance().getFriendAlias(friendPk);
Friend* newfriend = new Friend(friendId, friendPk, alias);
friendList[friendId] = newfriend;
key2id[friendPk.getKey()] = friendId;
key2id[friendPk.getByteArray()] = friendId;
return newfriend;
}
@ -71,7 +71,7 @@ void FriendList::clear()
Friend* FriendList::findFriend(const ToxPk& friendPk)
{
auto id = key2id.find(friendPk.getKey());
auto id = key2id.find(friendPk.getByteArray());
if (id != key2id.end()) {
Friend* f = findFriend(*id);
if (!f)

View File

@ -24,14 +24,14 @@
QHash<int, Group*> GroupList::groupList;
Group* GroupList::addGroup(int groupId, const QString& name, bool isAvGroupchat,
Group* GroupList::addGroup(int groupId, const GroupId& persistentGroupId, const QString& name, bool isAvGroupchat,
const QString& selfName)
{
auto checker = groupList.find(groupId);
if (checker != groupList.end())
qWarning() << "addGroup: groupId already taken";
Group* newGroup = new Group(groupId, name, isAvGroupchat, selfName);
Group* newGroup = new Group(groupId, persistentGroupId, name, isAvGroupchat, selfName);
groupList[groupId] = newGroup;
return newGroup;

View File

@ -20,6 +20,8 @@
#ifndef GROUPLIST_H
#define GROUPLIST_H
#include "src/core/groupid.h"
template <class A, class B>
class QHash;
template <class T>
@ -30,7 +32,7 @@ class QString;
class GroupList
{
public:
static Group* addGroup(int groupId, const QString& name, bool isAvGroupchat, const QString& selfName);
static Group* addGroup(int groupId, const GroupId& persistentGroupId, const QString& name, bool isAvGroupchat, const QString& selfName);
static Group* findGroup(int groupId);
static void removeGroup(int groupId, bool fake = false);
static QList<Group*> getAllGroups();

View File

@ -365,8 +365,6 @@ int main(int argc, char* argv[])
QObject::connect(a.get(), &QApplication::aboutToQuit, cleanup);
qRegisterMetaType<ReceiptNum>();
qRegisterMetaType<RowId>();
// Run
int errorcode = a->exec();

View File

@ -20,6 +20,7 @@
#ifndef CONTACT_H
#define CONTACT_H
#include "src/core/contactid.h"
#include <QObject>
#include <QString>
@ -32,7 +33,7 @@ public:
virtual void setName(const QString& name) = 0;
virtual QString getDisplayedName() const = 0;
virtual uint32_t getId() const = 0;
virtual const ContactId& getPersistentId() const = 0;
virtual void setEventFlag(bool flag) = 0;
virtual bool getEventFlag() const = 0;

View File

@ -137,6 +137,11 @@ uint32_t Friend::getId() const
return friendId;
}
const ContactId& Friend::getPersistentId() const
{
return friendPk;
}
void Friend::setEventFlag(bool flag)
{
hasNewEvents = flag;

View File

@ -23,6 +23,7 @@
#include "contact.h"
#include "src/core/core.h"
#include "src/core/toxid.h"
#include "src/core/contactid.h"
#include <QObject>
#include <QString>
@ -47,6 +48,7 @@ public:
const ToxPk& getPublicKey() const;
uint32_t getId() const override;
const ContactId& getPersistentId() const override;
void setStatus(Status s);
Status getStatus() const;

View File

@ -22,6 +22,9 @@
#include "src/friendlist.h"
#include "src/core/core.h"
#include "src/core/coreav.h"
#include "src/core/contactid.h"
#include "src/core/groupid.h"
#include "src/core/toxpk.h"
#include "src/persistence/settings.h"
#include "src/widget/form/groupchatform.h"
#include "src/widget/groupwidget.h"
@ -29,10 +32,11 @@
static const int MAX_GROUP_TITLE_LENGTH = 128;
Group::Group(int groupId, const QString& name, bool isAvGroupchat, const QString& selfName)
Group::Group(int groupId, const GroupId persistentGroupId, const QString& name, bool isAvGroupchat, const QString& selfName)
: selfName{selfName}
, title{name}
, groupId(groupId)
, persistentGroupId{persistentGroupId}
, avGroupchat{isAvGroupchat}
{
// in groupchats, we only notify on messages containing your name <-- dumb
@ -134,6 +138,11 @@ uint32_t Group::getId() const
return groupId;
}
const ContactId& Group::getPersistentId() const
{
return persistentGroupId;
}
int Group::getPeersCount() const
{
return toxpks.size();

View File

@ -22,6 +22,8 @@
#include "contact.h"
#include "src/core/contactid.h"
#include "src/core/groupid.h"
#include "src/core/toxpk.h"
#include <QMap>
@ -32,10 +34,10 @@ class Group : public Contact
{
Q_OBJECT
public:
Group(int groupId, const QString& name, bool isAvGroupchat, const QString& selfName);
Group(int groupId, const GroupId persistentGroupId, const QString& name, bool isAvGroupchat, const QString& selfName);
bool isAvGroupchat() const;
uint32_t getId() const override;
const ContactId& getPersistentId() const override;
int getPeersCount() const;
void regeneratePeerList();
const QMap<ToxPk, QString>& getPeerList() const;
@ -73,6 +75,7 @@ private:
bool hasNewMessages;
bool userWasMentioned;
int groupId;
const GroupId persistentGroupId;
bool avGroupchat;
};

View File

@ -99,7 +99,11 @@ void Nexus::start()
qRegisterMetaType<std::shared_ptr<VideoFrame>>("std::shared_ptr<VideoFrame>");
qRegisterMetaType<ToxPk>("ToxPk");
qRegisterMetaType<ToxId>("ToxId");
qRegisterMetaType<ToxPk>("GroupId");
qRegisterMetaType<ToxPk>("ContactId");
qRegisterMetaType<GroupInvite>("GroupInvite");
qRegisterMetaType<ReceiptNum>("ReceiptNum");
qRegisterMetaType<RowId>("RowId");
qApp->setQuitOnLastWindowClosed(false);

View File

@ -394,7 +394,7 @@ QString Profile::avatarPath(const ToxPk& owner, bool forceUnencrypted)
}
QByteArray idData = ownerStr.toUtf8();
QByteArray pubkeyData = core->getSelfId().getPublicKey().getKey();
QByteArray pubkeyData = core->getSelfId().getPublicKey().getByteArray();
constexpr int hashSize = TOX_PUBLIC_KEY_SIZE;
static_assert(hashSize >= crypto_generichash_BYTES_MIN && hashSize <= crypto_generichash_BYTES_MAX,
"Hash size not supported by libsodium");
@ -428,7 +428,7 @@ QPixmap Profile::loadAvatar(const ToxPk& owner)
const QByteArray avatarData = loadAvatarData(owner);
if (avatarData.isEmpty()) {
pic = QPixmap::fromImage(Identicon(owner.getKey()).toImage(16));
pic = QPixmap::fromImage(Identicon(owner.getByteArray()).toImage(16));
} else {
pic.loadFromData(avatarData);
}
@ -478,7 +478,7 @@ void Profile::loadDatabase(const ToxId& id, QString password)
return;
}
QByteArray salt = id.getPublicKey().getKey();
QByteArray salt = id.getPublicKey().getByteArray();
if (salt.size() != TOX_PASS_SALT_LENGTH) {
qWarning() << "Couldn't compute salt from public key" << name;
GUI::showError(QObject::tr("Error"),
@ -511,7 +511,7 @@ void Profile::setAvatar(QByteArray pic)
avatarData = pic;
} else {
if (Settings::getInstance().getShowIdenticons()) {
const QImage identicon = Identicon(selfPk.getKey()).toImage(32);
const QImage identicon = Identicon(selfPk.getByteArray()).toImage(32);
pixmap = QPixmap::fromImage(identicon);
} else {
@ -541,7 +541,7 @@ void Profile::setFriendAvatar(const ToxPk& owner, QByteArray pic)
avatarData = pic;
emit friendAvatarSet(owner, pixmap);
} else if (Settings::getInstance().getShowIdenticons()) {
const QImage identicon = Identicon(owner.getKey()).toImage(32);
const QImage identicon = Identicon(owner.getByteArray()).toImage(32);
pixmap = QPixmap::fromImage(identicon);
emit friendAvatarSet(owner, pixmap);
} else {

View File

@ -320,7 +320,7 @@ void Settings::loadPersonal(QString profileName, const ToxEncrypt* passKey)
if (getEnableLogging())
fp.activity = ps.value("activity", QDate()).toDate();
friendLst.insert(ToxId(fp.addr).getPublicKey().getKey(), fp);
friendLst.insert(ToxId(fp.addr).getPublicKey().getByteArray(), fp);
}
ps.endArray();
}
@ -1312,7 +1312,7 @@ QString Settings::getAutoAcceptDir(const ToxPk& id) const
{
QMutexLocker locker{&bigLock};
auto it = friendLst.find(id.getKey());
auto it = friendLst.find(id.getByteArray());
if (it != friendLst.end())
return it->autoAcceptDir;
@ -1335,7 +1335,7 @@ Settings::AutoAcceptCallFlags Settings::getAutoAcceptCall(const ToxPk& id) const
{
QMutexLocker locker{&bigLock};
auto it = friendLst.find(id.getKey());
auto it = friendLst.find(id.getByteArray());
if (it != friendLst.end())
return it->autoAcceptCall;
@ -1358,7 +1358,7 @@ bool Settings::getAutoGroupInvite(const ToxPk& id) const
{
QMutexLocker locker{&bigLock};
auto it = friendLst.find(id.getKey());
auto it = friendLst.find(id.getByteArray());
if (it != friendLst.end()) {
return it->autoGroupInvite;
}
@ -1382,7 +1382,7 @@ QString Settings::getContactNote(const ToxPk& id) const
{
QMutexLocker locker{&bigLock};
auto it = friendLst.find(id.getKey());
auto it = friendLst.find(id.getByteArray());
if (it != friendLst.end())
return it->note;
@ -1980,7 +1980,7 @@ QString Settings::getFriendAddress(const QString& publicKey) const
{
QMutexLocker locker{&bigLock};
// TODO: using ToxId here is a hack
QByteArray key = ToxId(publicKey).getPublicKey().getKey();
QByteArray key = ToxId(publicKey).getPublicKey().getByteArray();
auto it = friendLst.find(key);
if (it != friendLst.end())
return it->addr;
@ -2000,7 +2000,7 @@ void Settings::updateFriendAddress(const QString& newAddr)
QString Settings::getFriendAlias(const ToxPk& id) const
{
QMutexLocker locker{&bigLock};
auto it = friendLst.find(id.getKey());
auto it = friendLst.find(id.getByteArray());
if (it != friendLst.end())
return it->alias;
@ -2017,7 +2017,7 @@ void Settings::setFriendAlias(const ToxPk& id, const QString& alias)
int Settings::getFriendCircleID(const ToxPk& id) const
{
QMutexLocker locker{&bigLock};
auto it = friendLst.find(id.getKey());
auto it = friendLst.find(id.getByteArray());
if (it != friendLst.end())
return it->circleID;
@ -2033,7 +2033,8 @@ void Settings::setFriendCircleID(const ToxPk& id, int circleID)
QDate Settings::getFriendActivity(const ToxPk& id) const
{
auto it = friendLst.find(id.getKey());
QMutexLocker locker{&bigLock};
auto it = friendLst.find(id.getByteArray());
if (it != friendLst.end())
return it->activity;
@ -2056,7 +2057,7 @@ void Settings::saveFriendSettings(const ToxPk& id)
void Settings::removeFriendSettings(const ToxPk& id)
{
QMutexLocker locker{&bigLock};
friendLst.remove(id.getKey());
friendLst.remove(id.getByteArray());
}
bool Settings::getFauxOfflineMessaging() const
@ -2375,9 +2376,9 @@ Settings::friendProp& Settings::getOrInsertFriendPropRef(const ToxPk& id)
{
// No mutex lock, this is a private fn that should only be called by other
// public functions that already locked the mutex
auto it = friendLst.find(id.getKey());
auto it = friendLst.find(id.getByteArray());
if (it == friendLst.end()) {
it = friendLst.insert(id.getKey(), friendProp{id.toString()});
it = friendLst.insert(id.getByteArray(), friendProp{id.toString()});
}
return *it;

View File

@ -307,7 +307,7 @@ void AddFriendForm::setIdFromClipboard()
const QString trimmedId = clipboard->text().trimmed();
const QString strippedId = getToxId(trimmedId);
const Core* core = Core::getInstance();
const bool isSelf = ToxId(strippedId) != core->getSelfId();
const bool isSelf = ToxId::isToxId(strippedId) && ToxId(strippedId) != core->getSelfId();
if (!strippedId.isEmpty() && ToxId::isToxId(strippedId) && isSelf) {
toxId.setText(trimmedId);
}

View File

@ -234,7 +234,7 @@ void Widget::init()
updateCheck->checkForUpdate();
#endif
Core* core = Nexus::getCore();
core = Nexus::getCore();
CoreFile* coreFile = core->getCoreFile();
Profile* profile = Nexus::getProfile();
profileInfo = new ProfileInfo(core, profile);
@ -256,7 +256,7 @@ void Widget::init()
connect(ui->statusLabel, &CroppingLabel::editFinished, this, &Widget::onStatusMessageChanged);
connect(ui->mainSplitter, &QSplitter::splitterMoved, this, &Widget::onSplitterMoved);
connect(addFriendForm, &AddFriendForm::friendRequested, this, &Widget::friendRequested);
connect(groupInviteForm, &GroupInviteForm::groupCreate, Core::getInstance(), &Core::createGroup);
connect(groupInviteForm, &GroupInviteForm::groupCreate, core, &Core::createGroup);
connect(timer, &QTimer::timeout, this, &Widget::onUserAwayCheck);
connect(timer, &QTimer::timeout, this, &Widget::onEventIconTick);
connect(timer, &QTimer::timeout, this, &Widget::onTryCreateTrayIcon);
@ -603,7 +603,7 @@ void Widget::resizeEvent(QResizeEvent* event)
QString Widget::getUsername()
{
return Nexus::getCore()->getUsername();
return core->getUsername();
}
void Widget::onSelfAvatarLoaded(const QPixmap& pic)
@ -614,13 +614,13 @@ void Widget::onSelfAvatarLoaded(const QPixmap& pic)
void Widget::onConnected()
{
ui->statusButton->setEnabled(true);
emit statusSet(Nexus::getCore()->getStatus());
emit statusSet(core->getStatus());
}
void Widget::onDisconnected()
{
ui->statusButton->setEnabled(false);
emit Core::getInstance()->statusSet(Status::Offline);
emit core->statusSet(Status::Offline);
}
void Widget::onFailedToStartCore()
@ -909,7 +909,7 @@ void Widget::setUsername(const QString& username)
void Widget::onStatusMessageChanged(const QString& newStatusMessage)
{
// Keep old status message until Core tells us to set it.
Nexus::getCore()->setStatusMessage(newStatusMessage);
core->setStatusMessage(newStatusMessage);
}
void Widget::setStatusMessage(const QString& statusMessage)
@ -965,7 +965,7 @@ void Widget::onStopNotification()
void Widget::onRejectCall(uint32_t friendId)
{
CoreAV* const av = Core::getInstance()->getAv();
CoreAV* const av = core->getAv();
av->cancelCall(friendId);
}
@ -1447,7 +1447,7 @@ bool Widget::newMessageAlert(QWidget* currentWindow, bool isActive, bool sound,
#endif
eventFlag = true;
}
bool isBusy = Nexus::getCore()->getStatus() == Status::Busy;
bool isBusy = core->getStatus() == Status::Busy;
bool busySound = settings.getBusySound();
bool notifySound = settings.getNotifySound();
@ -1518,7 +1518,7 @@ void Widget::removeFriend(Friend* f, bool fake)
FriendList::removeFriend(friendId, fake);
if (!fake) {
Nexus::getCore()->removeFriend(friendId);
core->removeFriend(friendId);
}
friendWidgets.remove(friendId);
@ -1585,7 +1585,7 @@ ContentDialog* Widget::createContentDialog() const
connect(contentDialog, &ContentDialog::friendDialogShown, this, &Widget::onFriendDialogShown);
connect(contentDialog, &ContentDialog::groupDialogShown, this, &Widget::onGroupDialogShown);
connect(Core::getInstance(), &Core::usernameSet, contentDialog, &ContentDialog::setUsername);
connect(core, &Core::usernameSet, contentDialog, &ContentDialog::setUsername);
connect(&settings, &Settings::groupchatPositionChanged, contentDialog, &ContentDialog::reorderLayouts);
#ifdef Q_OS_MAC
@ -1604,10 +1604,11 @@ ContentLayout* Widget::createContentDialog(DialogType type) const
class Dialog : public ActivateDialog
{
public:
explicit Dialog(DialogType type, Settings& settings)
explicit Dialog(DialogType type, Settings& settings, Core* core)
: ActivateDialog(nullptr, Qt::Window)
, type(type)
, settings(settings)
, core{core}
{
restoreGeometry(settings.getDialogSettingsGeometry());
Translator::registerHandler(std::bind(&Dialog::retranslateUi, this), this);
@ -1615,7 +1616,7 @@ ContentLayout* Widget::createContentDialog(DialogType type) const
setWindowIcon(QIcon(":/img/icons/qtox.svg"));
setStyleSheet(Style::getStylesheet("window/general.css"));
connect(Core::getInstance(), &Core::usernameSet, this, &Dialog::retranslateUi);
connect(core, &Core::usernameSet, this, &Dialog::retranslateUi);
}
~Dialog()
@ -1627,7 +1628,7 @@ ContentLayout* Widget::createContentDialog(DialogType type) const
void retranslateUi()
{
setWindowTitle(Core::getInstance()->getUsername() + QStringLiteral(" - ")
setWindowTitle(core->getUsername() + QStringLiteral(" - ")
+ Widget::fromDialogType(type));
}
@ -1647,9 +1648,10 @@ ContentLayout* Widget::createContentDialog(DialogType type) const
private:
DialogType type;
Settings& settings;
Core* core;
};
Dialog* dialog = new Dialog(type, settings);
Dialog* dialog = new Dialog(type, settings, core);
dialog->setAttribute(Qt::WA_DeleteOnClose);
ContentLayout* contentLayoutDialog = new ContentLayout(dialog);
@ -1678,7 +1680,7 @@ void Widget::copyFriendIdToClipboard(int friendId)
Friend* f = FriendList::findFriend(friendId);
if (f != nullptr) {
QClipboard* clipboard = QApplication::clipboard();
const ToxPk& pk = Nexus::getCore()->getFriendPublicKey(f->getId());
const ToxPk& pk = core->getFriendPublicKey(f->getId());
clipboard->setText(pk.toString(), QClipboard::Clipboard);
}
}
@ -1713,7 +1715,7 @@ void Widget::onGroupInviteReceived(const GroupInvite& inviteInfo)
void Widget::onGroupInviteAccepted(const GroupInvite& inviteInfo)
{
const uint32_t groupId = Core::getInstance()->joinGroupchat(inviteInfo);
const uint32_t groupId = core->joinGroupchat(inviteInfo);
if (groupId == std::numeric_limits<uint32_t>::max()) {
qWarning() << "onGroupInviteAccepted: Unable to accept group invite";
return;
@ -1726,7 +1728,6 @@ void Widget::onGroupMessageReceived(int groupnumber, int peernumber, const QStri
Group* g = GroupList::findGroup(groupnumber);
assert(g);
const Core* core = Core::getInstance();
ToxPk author = core->getGroupPeerPk(groupnumber, peernumber);
bool isSelf = author == core->getSelfId().getPublicKey();
@ -1816,7 +1817,7 @@ void Widget::removeGroup(Group* g, bool fake)
}
if (!fake) {
Nexus::getCore()->removeGroup(groupId);
core->removeGroup(groupId);
}
contactListWidget->removeGroupWidget(widget); // deletes widget
@ -1840,7 +1841,7 @@ void Widget::removeGroup(int groupId)
removeGroup(GroupList::findGroup(groupId));
}
Group* Widget::createGroup(int groupId)
Group* Widget::createGroup(int groupId, const GroupId& groupPersistentId)
{
Group* g = GroupList::findGroup(groupId);
if (g) {
@ -1849,10 +1850,10 @@ Group* Widget::createGroup(int groupId)
}
const auto groupName = tr("Groupchat #%1").arg(groupId);
Core* core = Nexus::getCore();
Core* core = core;
bool enabled = core->getGroupAvEnabled(groupId);
Group* newgroup = GroupList::addGroup(groupId, groupName, enabled, core->getUsername());
Group* newgroup = GroupList::addGroup(groupId, groupPersistentId, groupName, enabled, core->getUsername());
std::shared_ptr<GroupChatroom> chatroom(new GroupChatroom(newgroup));
const auto compact = settings.getCompactLayout();
auto widget = new GroupWidget(chatroom, compact);
@ -1886,9 +1887,9 @@ Group* Widget::createGroup(int groupId)
return newgroup;
}
void Widget::onEmptyGroupCreated(int groupId, const QString& title)
void Widget::onEmptyGroupCreated(int groupId, const GroupId& groupPersistentId, const QString& title)
{
Group* group = createGroup(groupId);
Group* group = createGroup(groupId, groupPersistentId);
if (!group) {
return;
}
@ -2028,7 +2029,7 @@ void Widget::setStatusOnline()
return;
}
Nexus::getCore()->setStatus(Status::Online);
core->setStatus(Status::Online);
}
void Widget::setStatusAway()
@ -2037,7 +2038,7 @@ void Widget::setStatusAway()
return;
}
Nexus::getCore()->setStatus(Status::Away);
core->setStatus(Status::Away);
}
void Widget::setStatusBusy()
@ -2046,7 +2047,7 @@ void Widget::setStatusBusy()
return;
}
Nexus::getCore()->setStatus(Status::Busy);
core->setStatus(Status::Busy);
}
void Widget::onGroupSendFailed(int groupId)
@ -2346,7 +2347,7 @@ void Widget::friendListContextMenu(const QPoint& pos)
if (chosenAction == addCircleAction) {
contactListWidget->addCircleWidget();
} else if (chosenAction == createGroupAction) {
Nexus::getCore()->createGroup();
core->createGroup();
}
}
@ -2411,7 +2412,7 @@ void Widget::setActiveToolMenuButton(ActiveToolMenuButton newActiveButton)
void Widget::retranslateUi()
{
Core* core = Nexus::getCore();
Core* core = core;
ui->retranslateUi(this);
setUsername(core->getUsername());
setStatusMessage(core->getStatusMessage());
@ -2473,6 +2474,6 @@ void Widget::focusChatInput()
void Widget::refreshPeerListsLocal(const QString &username)
{
for (Group* g : GroupList::getAllGroups()) {
g->updateUsername(Core::getInstance()->getSelfPublicKey(), username);
g->updateUsername(core->getSelfPublicKey(), username);
}
}

View File

@ -31,6 +31,8 @@
#include "src/core/core.h"
#include "src/core/toxfile.h"
#include "src/core/groupid.h"
#include "src/core/toxpk.h"
#include "src/core/toxid.h"
#if DESKTOP_NOTIFICATIONS
#include "src/platform/desktop_notifications/desktopnotify.h"
@ -168,7 +170,7 @@ public slots:
void onFriendMessageReceived(int friendId, const QString& message, bool isAction);
void onFriendRequestReceived(const ToxPk& friendPk, const QString& message);
void updateFriendActivity(const Friend* frnd);
void onEmptyGroupCreated(int groupId, const QString& title);
void onEmptyGroupCreated(int groupId, const GroupId& groupPersistentId, const QString& title);
void onGroupInviteReceived(const GroupInvite& inviteInfo);
void onGroupInviteAccepted(const GroupInvite& inviteInfo);
void onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction);
@ -239,7 +241,7 @@ private:
bool newMessageAlert(QWidget* currentWindow, bool isActive, bool sound = true, bool notify = true);
void setActiveToolMenuButton(ActiveToolMenuButton newActiveButton);
void hideMainForms(GenericChatroomWidget* chatroomWidget);
Group* createGroup(int groupId);
Group* createGroup(int groupId, const GroupId& groupPersistentId);
void removeFriend(Friend* f, bool fake = false);
void removeGroup(Group* g, bool fake = false);
void saveWindowGeometry();
@ -316,6 +318,7 @@ private:
QMap<uint32_t, GroupWidget*> groupWidgets;
QMap<uint32_t, std::shared_ptr<GroupChatroom>> groupChatrooms;
QMap<uint32_t, QSharedPointer<GroupChatForm>> groupChatForms;
Core* core = nullptr;
#if DESKTOP_NOTIFICATIONS
DesktopNotify notifier;

View File

@ -17,7 +17,12 @@
along with qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#include "src/core/contactid.h"
#include "src/core/toxpk.h"
#include "src/core/toxid.h"
#include "src/core/groupid.h"
#include <tox/tox.h>
#include <QtTest/QtTest>
#include <QByteArray>
@ -35,7 +40,7 @@ const QString echoStr =
QStringLiteral("76518406F6A9F2217E8DC487CC783C25CC16A15EB36FF32E335A235342C48A39");
const QByteArray echoPk = QByteArray::fromHex(echoStr.toLatin1());
class TestToxPk : public QObject
class TestContactId : public QObject
{
Q_OBJECT
private slots:
@ -43,16 +48,17 @@ private slots:
void equalTest();
void clearTest();
void copyTest();
void publicKeyTest();
void dataTest();
void sizeTest();
};
void TestToxPk::toStringTest()
void TestContactId::toStringTest()
{
ToxPk pk(testPk);
QVERIFY(testStr == pk.toString());
}
void TestToxPk::equalTest()
void TestContactId::equalTest()
{
ToxPk pk1(testPk);
ToxPk pk2(testPk);
@ -62,7 +68,7 @@ void TestToxPk::equalTest()
QVERIFY(!(pk1 != pk2));
}
void TestToxPk::clearTest()
void TestContactId::clearTest()
{
ToxPk empty;
ToxPk pk(testPk);
@ -70,22 +76,29 @@ void TestToxPk::clearTest()
QVERIFY(!pk.isEmpty());
}
void TestToxPk::copyTest()
void TestContactId::copyTest()
{
ToxPk src(testPk);
ToxPk copy = src;
QVERIFY(copy == src);
}
void TestToxPk::publicKeyTest()
void TestContactId::dataTest()
{
ToxPk pk(testPk);
QVERIFY(testPk == pk.getKey());
for (int i = 0; i < ToxPk::getPkSize(); i++) {
QVERIFY(testPkArray[i] == pk.getBytes()[i]);
QVERIFY(testPk == pk.getByteArray());
for (int i = 0; i < pk.getSize(); i++) {
QVERIFY(testPkArray[i] == pk.getData()[i]);
}
}
QTEST_GUILESS_MAIN(TestToxPk)
#include "toxpk_test.moc"
void TestContactId::sizeTest()
{
ToxPk pk;
GroupId id;
QVERIFY(pk.getSize() == TOX_PUBLIC_KEY_SIZE);
QVERIFY(id.getSize() == TOX_CONFERENCE_UID_SIZE);
}
QTEST_GUILESS_MAIN(TestContactId)
#include "contactid_test.moc"