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/toxfilepause.h
src/core/toxid.cpp src/core/toxid.cpp
src/core/toxid.h src/core/toxid.h
src/core/groupid.cpp
src/core/groupid.h
src/core/toxlogger.cpp src/core/toxlogger.cpp
src/core/toxlogger.h src/core/toxlogger.h
src/core/toxoptions.cpp src/core/toxoptions.cpp
src/core/toxoptions.h src/core/toxoptions.h
src/core/toxpk.cpp src/core/toxpk.cpp
src/core/toxpk.h src/core/toxpk.h
src/core/contactid.cpp
src/core/contactid.h
src/core/toxstring.cpp src/core/toxstring.cpp
src/core/toxstring.h src/core/toxstring.h
src/friendlist.cpp src/friendlist.cpp

View File

@ -19,7 +19,7 @@ function(auto_test subsystem module)
endfunction() endfunction()
auto_test(core core) auto_test(core core)
auto_test(core toxpk) auto_test(core contactid)
auto_test(core toxid) auto_test(core toxid)
auto_test(core toxstring) auto_test(core toxstring)
auto_test(chatlog textformatter) 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(); 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)) { if (!tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, nullptr)) {
qDebug() << "Error bootstrapping from " + dhtServer.name; qDebug() << "Error bootstrapping from " + dhtServer.name;
@ -599,7 +599,7 @@ void Core::acceptFriendRequest(const ToxPk& friendPk)
{ {
QMutexLocker ml{&coreLoopLock}; QMutexLocker ml{&coreLoopLock};
// TODO: error handling // 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()) { if (friendId == std::numeric_limits<uint32_t>::max()) {
emit failedToAddFriend(friendPk); emit failedToAddFriend(friendPk);
} else { } else {
@ -1027,17 +1027,18 @@ void Core::loadGroups()
for(size_t i = 0; i < groupCount; ++i) { for(size_t i = 0; i < groupCount; ++i) {
TOX_ERR_CONFERENCE_TITLE error; 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)) { if (LogConferenceTitleError(error)) {
continue; continue;
} }
QByteArray name(titleSize, Qt::Uninitialized); 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)) { if (LogConferenceTitleError(error)) {
continue; continue;
} }
emit emptyGroupCreated(static_cast<int>(groupIds[i]), ToxString(name).getQString()); emit emptyGroupCreated(groupId, getGroupPersistentId(groupId), ToxString(name).getQString());
} }
delete[] groupIds; 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. * @brief Get number of peers in the conference.
* @return The number of peers in the conference. UINT32_MAX on failure. * @return The number of peers in the conference. UINT32_MAX on failure.
@ -1323,7 +1337,7 @@ int Core::createGroup(uint8_t type)
switch (error) { switch (error) {
case TOX_ERR_CONFERENCE_NEW_OK: case TOX_ERR_CONFERENCE_NEW_OK:
emit emptyGroupCreated(groupId); emit emptyGroupCreated(groupId, getGroupPersistentId(groupId));
return groupId; return groupId;
case TOX_ERR_CONFERENCE_NEW_INIT: case TOX_ERR_CONFERENCE_NEW_INIT:
@ -1335,7 +1349,7 @@ int Core::createGroup(uint8_t type)
} }
} else if (type == TOX_CONFERENCE_TYPE_AV) { } else if (type == TOX_CONFERENCE_TYPE_AV) {
uint32_t groupId = toxav_add_av_groupchat(tox.get(), CoreAV::groupCallCallback, this); uint32_t groupId = toxav_add_av_groupchat(tox.get(), CoreAV::groupCallCallback, this);
emit emptyGroupCreated(groupId); emit emptyGroupCreated(groupId, getGroupPersistentId(groupId));
return groupId; return groupId;
} else { } else {
qWarning() << "createGroup: Unknown type " << type; qWarning() << "createGroup: Unknown type " << type;
@ -1366,7 +1380,7 @@ bool Core::hasFriendWithPublicKey(const ToxPk& publicKey) const
} }
// TODO: error handling // 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(); return friendId != std::numeric_limits<uint32_t>::max();
} }
@ -1443,7 +1457,7 @@ QString Core::getPeerName(const ToxPk& id) const
QMutexLocker ml{&coreLoopLock}; QMutexLocker ml{&coreLoopLock};
QString name; 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()) { if (friendId == std::numeric_limits<uint32_t>::max()) {
qWarning() << "getPeerName: No such peer"; qWarning() << "getPeerName: No such peer";
return name; return name;

View File

@ -23,6 +23,8 @@
#include "toxfile.h" #include "toxfile.h"
#include "toxid.h" #include "toxid.h"
#include "toxpk.h"
#include "groupid.h"
#include "src/util/strongtype.h" #include "src/util/strongtype.h"
#include <tox/tox.h> #include <tox/tox.h>
@ -77,10 +79,9 @@ public:
static const QString TOX_EXT; static const QString TOX_EXT;
static QStringList splitMessage(const QString& message, int maxLen); static QStringList splitMessage(const QString& message, int maxLen);
QString getPeerName(const ToxPk& id) const; QString getPeerName(const ToxPk& id) const;
QVector<uint32_t> getFriendList() const; QVector<uint32_t> getFriendList() const;
GroupId getGroupPersistentId(uint32_t groupNumber);
uint32_t getGroupNumberPeers(int groupId) const; uint32_t getGroupNumberPeers(int groupId) const;
QString getGroupPeerName(int groupId, int peerId) const; QString getGroupPeerName(int groupId, int peerId) const;
ToxPk getGroupPeerPk(int groupId, int peerId) const; ToxPk getGroupPeerPk(int groupId, int peerId) const;
@ -171,7 +172,7 @@ signals:
void friendRemoved(uint32_t friendId); void friendRemoved(uint32_t friendId);
void friendLastSeenChanged(uint32_t friendId, const QDateTime& dateTime); 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 groupInviteReceived(const GroupInvite& inviteInfo);
void groupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction); void groupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction);
void groupNamelistChanged(int groupnumber, int peernumber, uint8_t change); 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 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 <QByteArray>
#include <QString> #include <QString>
#include <cassert>
/** /**
* @class ToxPk * @class ToxPk
* @brief This class represents a Tox Public Key, which is a part of Tox ID. * @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. * @brief The default constructor. Creates an empty Tox key.
*/ */
ToxPk::ToxPk() ToxPk::ToxPk()
: key() : ContactId()
{ {
} }
@ -23,7 +25,7 @@ ToxPk::ToxPk()
* @param other ToxPk to copy * @param other ToxPk to copy
*/ */
ToxPk::ToxPk(const ToxPk& other) 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. * TOX_PUBLIC_KEY_SIZE, else the ToxPk will be empty.
*/ */
ToxPk::ToxPk(const QByteArray& rawId) 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. * TOX_PUBLIC_KEY_SIZE from the specified buffer.
*/ */
ToxPk::ToxPk(const uint8_t* rawId) 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. * @brief Get size of public key in bytes.
* @return 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; return TOX_PUBLIC_KEY_SIZE;
} }

View File

@ -1,32 +1,18 @@
#ifndef TOXPK_H #ifndef TOXPK_H
#define TOXPK_H #define TOXPK_H
#include "src/core/contactid.h"
#include <QByteArray> #include <QByteArray>
#include <QString>
#include <cstdint> #include <cstdint>
class ToxPk class ToxPk : public ContactId
{ {
public: public:
ToxPk(); ToxPk();
ToxPk(const ToxPk& other); ToxPk(const ToxPk& other);
explicit ToxPk(const QByteArray& rawId); explicit ToxPk(const QByteArray& rawId);
explicit ToxPk(const uint8_t* rawId); explicit ToxPk(const uint8_t* rawId);
ToxPk& operator=(const ToxPk& other) = default; int getSize() const override;
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;
}; };
#endif // TOXPK_H #endif // TOXPK_H

View File

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

View File

@ -24,14 +24,14 @@
QHash<int, Group*> GroupList::groupList; 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) const QString& selfName)
{ {
auto checker = groupList.find(groupId); auto checker = groupList.find(groupId);
if (checker != groupList.end()) if (checker != groupList.end())
qWarning() << "addGroup: groupId already taken"; 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; groupList[groupId] = newGroup;
return newGroup; return newGroup;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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