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

Merge branch 'pr846'

This commit is contained in:
Tux3 / Mlkj / !Lev.uXFMLA 2014-11-25 19:58:57 +01:00
commit 8d26b4fb34
No known key found for this signature in database
GPG Key ID: 7E086DD661263264
19 changed files with 315 additions and 178 deletions

View File

@ -457,8 +457,7 @@ void Core::onAction(Tox*/* tox*/, int friendId, const uint8_t *cMessage, uint16_
void Core::onGroupAction(Tox*, int groupnumber, int peernumber, const uint8_t *action, uint16_t length, void* _core) void Core::onGroupAction(Tox*, int groupnumber, int peernumber, const uint8_t *action, uint16_t length, void* _core)
{ {
Core* core = static_cast<Core*>(_core); Core* core = static_cast<Core*>(_core);
emit core->groupMessageReceived(groupnumber, CString::toString(action, length), emit core->groupMessageReceived(groupnumber, peernumber, CString::toString(action, length), true);
core->getGroupPeerName(groupnumber, peernumber), true);
} }
void Core::onGroupInvite(Tox*, int friendnumber, uint8_t type, const uint8_t *data, uint16_t length,void *core) void Core::onGroupInvite(Tox*, int friendnumber, uint8_t type, const uint8_t *data, uint16_t length,void *core)
@ -483,8 +482,8 @@ void Core::onGroupInvite(Tox*, int friendnumber, uint8_t type, const uint8_t *da
void Core::onGroupMessage(Tox*, int groupnumber, int peernumber, const uint8_t * message, uint16_t length, void *_core) void Core::onGroupMessage(Tox*, int groupnumber, int peernumber, const uint8_t * message, uint16_t length, void *_core)
{ {
Core* core = static_cast<Core*>(_core); Core* core = static_cast<Core*>(_core);
emit core->groupMessageReceived(groupnumber, CString::toString(message, length),
core->getGroupPeerName(groupnumber, peernumber), false); emit core->groupMessageReceived(groupnumber, peernumber, CString::toString(message, length), false);
} }
void Core::onGroupNamelistChange(Tox*, int groupnumber, int peernumber, uint8_t change, void *core) void Core::onGroupNamelistChange(Tox*, int groupnumber, int peernumber, uint8_t change, void *core)
@ -1463,6 +1462,22 @@ QString Core::getGroupPeerName(int groupId, int peerId) const
return name; return name;
} }
ToxID Core::getGroupPeerToxID(int groupId, int peerId) const
{
ToxID peerToxID;
uint8_t rawID[TOX_CLIENT_ID_SIZE];
int res = tox_group_peer_pubkey(tox, groupId, peerId, rawID);
if (res == -1)
{
qWarning() << "Core::getGroupPeerToxID: Unknown error";
return peerToxID;
}
peerToxID = ToxID::fromString(CUserId::toString(rawID));
return peerToxID;
}
QList<QString> Core::getGroupPeerNames(int groupId) const QList<QString> Core::getGroupPeerNames(int groupId) const
{ {
QList<QString> names; QList<QString> names;

View File

@ -53,6 +53,7 @@ public:
int getGroupNumberPeers(int groupId) const; ///< Return the number of peers in the group chat on success, or -1 on failure int getGroupNumberPeers(int groupId) const; ///< Return the number of peers in the group chat on success, or -1 on failure
QString getGroupPeerName(int groupId, int peerId) const; ///< Get the name of a peer of a group QString getGroupPeerName(int groupId, int peerId) const; ///< Get the name of a peer of a group
ToxID getGroupPeerToxID(int groupId, int peerId) const; ///< Get the ToxID of a peer of a group
QList<QString> getGroupPeerNames(int groupId) const; ///< Get the names of the peers of a group QList<QString> getGroupPeerNames(int groupId) const; ///< Get the names of the peers of a group
QString getFriendAddress(int friendNumber) const; ///< Get the full address if known, or Tox ID of a friend QString getFriendAddress(int friendNumber) const; ///< Get the full address if known, or Tox ID of a friend
QString getFriendUsername(int friendNumber) const; ///< Get the username of a friend QString getFriendUsername(int friendNumber) const; ///< Get the username of a friend
@ -160,7 +161,7 @@ signals:
void emptyGroupCreated(int groupnumber); void emptyGroupCreated(int groupnumber);
void groupInviteReceived(int friendnumber, uint8_t type, QByteArray publicKey); void groupInviteReceived(int friendnumber, uint8_t type, QByteArray publicKey);
void groupMessageReceived(int groupnumber, const QString& message, const QString& author, 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);
void groupTitleChanged(int groupnumber, const QString& author, const QString& title); void groupTitleChanged(int groupnumber, const QString& author, const QString& title);

View File

@ -61,6 +61,7 @@ void FriendList::clear()
{ {
for (auto friendptr : friendList) for (auto friendptr : friendList)
delete friendptr; delete friendptr;
friendList.clear();
} }
Friend* FriendList::findFriend(const ToxID& userId) Friend* FriendList::findFriend(const ToxID& userId)

View File

@ -26,7 +26,6 @@ struct ToxID;
class FriendList class FriendList
{ {
public: public:
FriendList();
static Friend* addFriend(int friendId, const ToxID &userId); static Friend* addFriend(int friendId, const ToxID &userId);
static Friend* findFriend(int friendId); static Friend* findFriend(int friendId);
static Friend* findFriend(const ToxID &userId); static Friend* findFriend(const ToxID &userId);

View File

@ -43,6 +43,7 @@ Group::~Group()
delete widget; delete widget;
} }
/*
void Group::addPeer(int peerId, QString name) void Group::addPeer(int peerId, QString name)
{ {
if (peers.contains(peerId)) if (peers.contains(peerId))
@ -63,10 +64,22 @@ void Group::removePeer(int peerId)
widget->onUserListChanged(); widget->onUserListChanged();
chatForm->onUserListChanged(); chatForm->onUserListChanged();
} }
*/
void Group::updatePeer(int peerId, QString name) void Group::updatePeer(int peerId, QString name)
{ {
ToxID id = Core::getInstance()->getGroupPeerToxID(groupId, peerId);
QString toxid = id.publicKey;
peers[peerId] = name; peers[peerId] = name;
toxids[toxid] = name;
Friend *f = FriendList::findFriend(id);
if (f)
{
peers[peerId] = f->getDisplayedName();
toxids[toxid] = f->getDisplayedName();
}
widget->onUserListChanged(); widget->onUserListChanged();
chatForm->onUserListChanged(); chatForm->onUserListChanged();
} }
@ -79,3 +92,91 @@ void Group::setName(const QString& name)
if (widget->isActive()) if (widget->isActive())
Widget::getInstance()->setWindowTitle(name); Widget::getInstance()->setWindowTitle(name);
} }
void Group::regeneratePeerList()
{
QList<QString> peerLst = Core::getInstance()->getGroupPeerNames(groupId);
peers.clear();
toxids.clear();
nPeers = peerLst.size();
for (int i = 0; i < peerLst.size(); i++)
{
ToxID id = Core::getInstance()->getGroupPeerToxID(groupId, i);
QString toxid = id.publicKey;
peers[i] = peerLst.at(i);
toxids[toxid] = peerLst.at(i);
Friend *f = FriendList::findFriend(id);
if (f)
{
peers[i] = f->getDisplayedName();
toxids[toxid] = f->getDisplayedName();
}
}
widget->onUserListChanged();
chatForm->onUserListChanged();
}
bool Group::isAvGroupchat() const
{
return avGroupchat;
}
int Group::getGroupId() const
{
return groupId;
}
int Group::getPeersCount() const
{
return nPeers;
}
GroupChatForm *Group::getChatForm()
{
return chatForm;
}
GroupWidget *Group::getGroupWidget()
{
return widget;
}
QStringList Group::getPeerList() const
{
return peers.values();
}
void Group::setEventFlag(int f)
{
hasNewMessages = f;
}
int Group::getEventFlag() const
{
return hasNewMessages;
}
void Group::setMentionedFlag(int f)
{
userWasMentioned = f;
}
int Group::getMentionedFlag() const
{
return userWasMentioned;
}
QString Group::resolveToxID(const ToxID &id) const
{
QString key = id.publicKey;
auto it = toxids.find(key);
if (it != toxids.end())
{
return *it;
}
return QString();
}

View File

@ -25,26 +25,50 @@
struct Friend; struct Friend;
class GroupWidget; class GroupWidget;
class GroupChatForm; class GroupChatForm;
struct ToxID;
class Group : public QObject class Group : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Group(int GroupId, QString Name, bool IsAvGroupchat); Group(int GroupId, QString Name, bool IsAvGroupchat);
~Group(); virtual ~Group();
bool isAvGroupchat() const;
int getGroupId() const;
int getPeersCount() const;
void regeneratePeerList();
QStringList getPeerList() const;
GroupChatForm *getChatForm();
GroupWidget *getGroupWidget();
void setEventFlag(int f);
int getEventFlag() const;
void setMentionedFlag(int f);
int getMentionedFlag() const;
/*
void addPeer(int peerId, QString name); void addPeer(int peerId, QString name);
void removePeer(int peerId); void removePeer(int peerId);
*/
void updatePeer(int peerId, QString newName); void updatePeer(int peerId, QString newName);
void setName(const QString& name); void setName(const QString& name);
public: QString resolveToxID(const ToxID &id) const;
int groupId;
QMap<int,QString> peers; private:
int nPeers;
GroupWidget* widget; GroupWidget* widget;
GroupChatForm* chatForm; GroupChatForm* chatForm;
QMap<int, QString> peers;
QMap<QString, QString> toxids;
int hasNewMessages, userWasMentioned; int hasNewMessages, userWasMentioned;
int groupId;
int nPeers;
bool avGroupchat; bool avGroupchat;
}; };
#endif // GROUP_H #endif // GROUP_H

View File

@ -16,32 +16,54 @@
#include "grouplist.h" #include "grouplist.h"
#include "group.h" #include "group.h"
#include <QHash>
#include <QDebug>
QList<Group*> GroupList::groupList; QHash<int, Group*> GroupList::groupList;
Group* GroupList::addGroup(int groupId, const QString& name, bool isAvGroupchat) Group* GroupList::addGroup(int groupId, const QString& name, bool isAvGroupchat)
{ {
auto checker = groupList.find(groupId);
if (checker != groupList.end())
qWarning() << "GroupList::addGroup: groupId already taken";
Group* newGroup = new Group(groupId, name, isAvGroupchat); Group* newGroup = new Group(groupId, name, isAvGroupchat);
groupList.append(newGroup); groupList[groupId] = newGroup;
return newGroup; return newGroup;
} }
Group* GroupList::findGroup(int groupId) Group* GroupList::findGroup(int groupId)
{ {
for (Group* g : groupList) auto g_it = groupList.find(groupId);
if (g->groupId == groupId) if (g_it != groupList.end())
return g; return *g_it;
return nullptr; return nullptr;
} }
void GroupList::removeGroup(int groupId, bool /*fake*/) void GroupList::removeGroup(int groupId, bool /*fake*/)
{ {
for (int i=0; i<groupList.size(); i++) auto g_it = groupList.find(groupId);
if (g_it != groupList.end())
{ {
if (groupList[i]->groupId == groupId) groupList.erase(g_it);
{
groupList.removeAt(i);
return;
}
} }
} }
QList<Group *> GroupList::getAllGroups()
{
QList<Group*> res;
for (auto it : groupList)
res.append(it);
return res;
}
void GroupList::clear()
{
for (auto groupptr : groupList)
delete groupptr;
groupList.clear();
}

View File

@ -17,21 +17,22 @@
#ifndef GROUPLIST_H #ifndef GROUPLIST_H
#define GROUPLIST_H #define GROUPLIST_H
template <typename T> template <class A, class B> class QHash;
class QList; template <class T> class QList;
class Group; class Group;
class QString; class QString;
class GroupList class GroupList
{ {
public: public:
GroupList();
static Group* addGroup(int groupId, const QString& name, bool isAvGroupchat); static Group* addGroup(int groupId, const QString& name, bool isAvGroupchat);
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 void clear();
public: private:
static QList<Group*> groupList; static QHash<int, Group*> groupList;
}; };
#endif // GROUPLIST_H #endif // GROUPLIST_H

View File

@ -216,8 +216,9 @@ void ChatForm::onFileRecvRequest(ToxFile file)
previousId = friendId; previousId = friendId;
} }
chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name), QString dateStr = QTime::currentTime().toString(Settings::getInstance().getTimestampFormat());
QTime::currentTime().toString("hh:mm"), false))); FileTransferAction *fa = new FileTransferAction(fileTrans, getElidedName(name), dateStr, false);
chatWidget->insertMessage(ChatActionPtr(fa));
if (!Settings::getInstance().getAutoAcceptDir(f->getToxID()).isEmpty() if (!Settings::getInstance().getAutoAcceptDir(f->getToxID()).isEmpty()
|| Settings::getInstance().getAutoSaveEnabled()) || Settings::getInstance().getAutoSaveEnabled())

View File

@ -31,6 +31,8 @@
#include "src/widget/tool/chattextedit.h" #include "src/widget/tool/chattextedit.h"
#include "src/widget/maskablepixmapwidget.h" #include "src/widget/maskablepixmapwidget.h"
#include "src/core.h" #include "src/core.h"
#include "src/grouplist.h"
#include "src/group.h"
#include "src/friendlist.h" #include "src/friendlist.h"
#include "src/friend.h" #include "src/friend.h"
@ -201,16 +203,6 @@ void GenericChatForm::onSaveLogClicked()
file.close(); file.close();
} }
/**
* @deprecated The only reason it's still alive is because the groupchat API is a bit limited
*/
void GenericChatForm::addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime)
{
MessageActionPtr ca = genMessageActionAction(author, message, isAction, datetime);
ca->markAsSent();
chatWidget->insertMessage(ca);
}
MessageActionPtr GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, MessageActionPtr GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction,
const QDateTime &datetime, bool isSent) const QDateTime &datetime, bool isSent)
{ {
@ -230,24 +222,16 @@ MessageActionPtr GenericChatForm::addSelfMessage(const QString &message, bool is
return ca; return ca;
} }
/**
* @deprecated The only reason it's still alive is because the groupchat API is a bit limited
*/
void GenericChatForm::addAlertMessage(const QString& author, QString message, QDateTime datetime)
{
QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
AlertAction *alact = new AlertAction(author, message, date);
alact->markAsSent();
chatWidget->insertMessage(ChatActionPtr(alact));
previousId.publicKey = author;
}
void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime) void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime)
{ {
QString authorStr = Core::getInstance()->getPeerName(author); QString authorStr = resolveToxID(author);
if (authorStr.isEmpty())
authorStr = author.publicKey;
QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
chatWidget->insertMessage(ChatActionPtr(new AlertAction(authorStr, message, date))); MessageActionPtr ca = MessageActionPtr(new AlertAction(authorStr, message, date));
ca->markAsSent();
chatWidget->insertMessage(ca);
previousId = author; previousId = author;
} }
@ -314,42 +298,6 @@ void GenericChatForm::clearChatArea(bool notinform)
emit chatAreaCleared(); emit chatAreaCleared();
} }
/**
* @deprecated The only reason it's still alive is because the groupchat API is a bit limited
*/
MessageActionPtr GenericChatForm::genMessageActionAction(const QString &author, QString message, bool isAction,
const QDateTime &datetime)
{
if (earliestMessage == nullptr)
{
earliestMessage = new QDateTime(datetime);
}
QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
bool isMe = (author == Widget::getInstance()->getUsername());
if (!isAction && message.startsWith("/me "))
{ // always render actions regardless of what core thinks
isAction = true;
message = message.right(message.length()-4);
}
if (isAction)
{
previousId = ToxID(); // next msg has a name regardless
return MessageActionPtr(new ActionAction (author, message, date, isMe));
}
MessageActionPtr res;
if (previousId.publicKey == author)
res = MessageActionPtr(new MessageAction(QString(), message, date, isMe));
else
res = MessageActionPtr(new MessageAction(getElidedName(author), message, date, isMe));
previousId.publicKey = author;
return res;
}
MessageActionPtr GenericChatForm::genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime) MessageActionPtr GenericChatForm::genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime)
{ {
if (earliestMessage == nullptr) if (earliestMessage == nullptr)
@ -365,11 +313,7 @@ MessageActionPtr GenericChatForm::genMessageActionAction(const ToxID& author, QS
if (isMe) if (isMe)
authorStr = core->getUsername(); authorStr = core->getUsername();
else { else {
Friend *f = FriendList::findFriend(author); authorStr = resolveToxID(author);
if (f)
authorStr = f->getDisplayedName();
else
authorStr = core->getPeerName(author);
} }
if (authorStr.isEmpty()) // Fallback if we can't find a username if (authorStr.isEmpty()) // Fallback if we can't find a username
@ -438,3 +382,21 @@ ChatActionPtr GenericChatForm::genSystemInfoAction(const QString &message, const
return ChatActionPtr(new SystemMessageAction(message, type, date)); return ChatActionPtr(new SystemMessageAction(message, type, date));
} }
QString GenericChatForm::resolveToxID(const ToxID &id)
{
Friend *f = FriendList::findFriend(id);
if (f)
{
return f->getDisplayedName();
} else {
for (auto it : GroupList::getAllGroups())
{
QString res = it->resolveToxID(id);
if (res.size())
return res;
}
}
return QString();
}

View File

@ -49,11 +49,9 @@ public:
virtual void setName(const QString &newName); virtual void setName(const QString &newName);
virtual void show(Ui::MainWindow &ui); virtual void show(Ui::MainWindow &ui);
void addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime); ///< Deprecated
MessageActionPtr addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); MessageActionPtr addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent);
MessageActionPtr addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); MessageActionPtr addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent);
void addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime); void addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime);
void addAlertMessage(const QString& author, QString message, QDateTime datetime); ///< Deprecated
void addAlertMessage(const ToxID& author, QString message, QDateTime datetime); void addAlertMessage(const ToxID& author, QString message, QDateTime datetime);
bool isEmpty(); bool isEmpty();
@ -74,11 +72,12 @@ protected slots:
protected: protected:
QString getElidedName(const QString& name); QString getElidedName(const QString& name);
MessageActionPtr genMessageActionAction(const QString& author, QString message, bool isAction, const QDateTime &datetime); ///< Deprecated
MessageActionPtr genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime); MessageActionPtr genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime);
MessageActionPtr genSelfActionAction(QString message, bool isAction, const QDateTime &datetime); MessageActionPtr genSelfActionAction(QString message, bool isAction, const QDateTime &datetime);
ChatActionPtr genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime); ChatActionPtr genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime);
QString resolveToxID(const ToxID &id);
ToxID previousId; ToxID previousId;
QMenu menu; QMenu menu;
int curRow; int curRow;

View File

@ -38,7 +38,7 @@ GroupChatForm::GroupChatForm(Group* chatGroup)
tabber = new TabCompleter(msgEdit, group); tabber = new TabCompleter(msgEdit, group);
fileButton->setEnabled(false); fileButton->setEnabled(false);
if (group->avGroupchat) if (group->isAvGroupchat())
{ {
videoButton->setEnabled(false); videoButton->setEnabled(false);
videoButton->setObjectName("grey"); videoButton->setObjectName("grey");
@ -51,10 +51,10 @@ GroupChatForm::GroupChatForm(Group* chatGroup)
micButton->setVisible(false); micButton->setVisible(false);
} }
nameLabel->setText(group->widget->getName()); nameLabel->setText(group->getGroupWidget()->getName());
nusersLabel->setFont(Style::getFont(Style::Medium)); nusersLabel->setFont(Style::getFont(Style::Medium));
nusersLabel->setText(GroupChatForm::tr("%1 users in chat","Number of users in chat").arg(group->peers.size())); nusersLabel->setText(GroupChatForm::tr("%1 users in chat","Number of users in chat").arg(group->getPeersCount()));
nusersLabel->setObjectName("statusLabel"); nusersLabel->setObjectName("statusLabel");
avatar->setPixmap(QPixmap(":/img/group_dark.png"), Qt::transparent); avatar->setPixmap(QPixmap(":/img/group_dark.png"), Qt::transparent);
@ -62,7 +62,7 @@ GroupChatForm::GroupChatForm(Group* chatGroup)
msgEdit->setObjectName("group"); msgEdit->setObjectName("group");
namesListLayout = new FlowLayout(0,5,0); namesListLayout = new FlowLayout(0,5,0);
QStringList names(group->peers.values()); QStringList names(group->getPeerList());
for (const QString& name : names) for (const QString& name : names)
namesListLayout->addWidget(new QLabel(name)); namesListLayout->addWidget(new QLabel(name));
@ -81,7 +81,7 @@ GroupChatForm::GroupChatForm(Group* chatGroup)
connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle())); connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle()));
connect(volButton, SIGNAL(clicked()), this, SLOT(onVolMuteToggle())); connect(volButton, SIGNAL(clicked()), this, SLOT(onVolMuteToggle()));
connect(nameLabel, &CroppingLabel::textChanged, this, [=](QString text, QString orig) connect(nameLabel, &CroppingLabel::textChanged, this, [=](QString text, QString orig)
{if (text != orig) emit groupTitleChanged(group->groupId, text.left(128));} ); {if (text != orig) emit groupTitleChanged(group->getGroupId(), text.left(128));} );
setAcceptDrops(true); setAcceptDrops(true);
} }
@ -97,15 +97,15 @@ void GroupChatForm::onSendTriggered()
if (msg.startsWith("/me ")) if (msg.startsWith("/me "))
{ {
msg = msg.right(msg.length() - 4); msg = msg.right(msg.length() - 4);
emit sendAction(group->groupId, msg); emit sendAction(group->getGroupId(), msg);
} else { } else {
emit sendMessage(group->groupId, msg); emit sendMessage(group->getGroupId(), msg);
} }
} }
void GroupChatForm::onUserListChanged() void GroupChatForm::onUserListChanged()
{ {
nusersLabel->setText(tr("%1 users in chat").arg(group->nPeers)); nusersLabel->setText(tr("%1 users in chat").arg(group->getPeersCount()));
QLayoutItem *child; QLayoutItem *child;
while ((child = namesListLayout->takeAt(0))) while ((child = namesListLayout->takeAt(0)))
@ -115,7 +115,7 @@ void GroupChatForm::onUserListChanged()
delete child; delete child;
} }
QStringList names(group->peers.values()); QStringList names(group->getPeerList());
unsigned nNames = names.size(); unsigned nNames = names.size();
for (unsigned i=0; i<nNames; ++i) for (unsigned i=0; i<nNames; ++i)
{ {
@ -139,7 +139,7 @@ void GroupChatForm::dropEvent(QDropEvent *ev)
if (ev->mimeData()->hasFormat("friend")) if (ev->mimeData()->hasFormat("friend"))
{ {
int friendId = ev->mimeData()->data("friend").toInt(); int friendId = ev->mimeData()->data("friend").toInt();
Core::getInstance()->groupInviteFriend(friendId, group->groupId); Core::getInstance()->groupInviteFriend(friendId, group->getGroupId());
} }
} }
@ -149,12 +149,12 @@ void GroupChatForm::onMicMuteToggle()
{ {
if (micButton->objectName() == "red") if (micButton->objectName() == "red")
{ {
Core::getInstance()->enableGroupCallMic(group->groupId); Core::getInstance()->enableGroupCallMic(group->getGroupId());
micButton->setObjectName("green"); micButton->setObjectName("green");
} }
else else
{ {
Core::getInstance()->disableGroupCallMic(group->groupId); Core::getInstance()->disableGroupCallMic(group->getGroupId());
micButton->setObjectName("red"); micButton->setObjectName("red");
} }
@ -168,12 +168,12 @@ void GroupChatForm::onVolMuteToggle()
{ {
if (volButton->objectName() == "red") if (volButton->objectName() == "red")
{ {
Core::getInstance()->enableGroupCallVol(group->groupId); Core::getInstance()->enableGroupCallVol(group->getGroupId());
volButton->setObjectName("green"); volButton->setObjectName("green");
} }
else else
{ {
Core::getInstance()->disableGroupCallVol(group->groupId); Core::getInstance()->disableGroupCallVol(group->getGroupId());
volButton->setObjectName("red"); volButton->setObjectName("red");
} }
@ -185,7 +185,7 @@ void GroupChatForm::onCallClicked()
{ {
if (!inCall) if (!inCall)
{ {
Core::getInstance()->joinGroupCall(group->groupId); Core::getInstance()->joinGroupCall(group->getGroupId());
audioInputFlag = true; audioInputFlag = true;
audioOutputFlag = true; audioOutputFlag = true;
callButton->setObjectName("red"); callButton->setObjectName("red");
@ -194,7 +194,7 @@ void GroupChatForm::onCallClicked()
} }
else else
{ {
Core::getInstance()->leaveGroupCall(group->groupId); Core::getInstance()->leaveGroupCall(group->getGroupId());
audioInputFlag = false; audioInputFlag = false;
audioOutputFlag = false; audioOutputFlag = false;
micButton->setObjectName("green"); micButton->setObjectName("green");
@ -216,9 +216,9 @@ void GroupChatForm::keyPressEvent(QKeyEvent* ev)
if (ev->key() == Qt::Key_P && inCall) if (ev->key() == Qt::Key_P && inCall)
{ {
Core* core = Core::getInstance(); Core* core = Core::getInstance();
if (!core->isGroupCallMicEnabled(group->groupId)) if (!core->isGroupCallMicEnabled(group->getGroupId()))
{ {
core->enableGroupCallMic(group->groupId); core->enableGroupCallMic(group->getGroupId());
micButton->setObjectName("green"); micButton->setObjectName("green");
micButton->style()->polish(micButton); micButton->style()->polish(micButton);
Style::repolish(micButton); Style::repolish(micButton);
@ -235,9 +235,9 @@ void GroupChatForm::keyReleaseEvent(QKeyEvent* ev)
if (ev->key() == Qt::Key_P && inCall) if (ev->key() == Qt::Key_P && inCall)
{ {
Core* core = Core::getInstance(); Core* core = Core::getInstance();
if (core->isGroupCallMicEnabled(group->groupId)) if (core->isGroupCallMicEnabled(group->getGroupId()))
{ {
core->disableGroupCallMic(group->groupId); core->disableGroupCallMic(group->getGroupId());
micButton->setObjectName("red"); micButton->setObjectName("red");
micButton->style()->polish(micButton); micButton->style()->polish(micButton);
Style::repolish(micButton); Style::repolish(micButton);

View File

@ -33,15 +33,13 @@ AVForm::AVForm() :
bodyUI = new Ui::AVSettings; bodyUI = new Ui::AVSettings;
bodyUI->setupUi(this); bodyUI->setupUi(this);
getAudioOutDevices();
getAudioInDevices();
connect(Camera::getInstance(), &Camera::propProbingFinished, this, &AVForm::onPropProbingFinished); connect(Camera::getInstance(), &Camera::propProbingFinished, this, &AVForm::onPropProbingFinished);
connect(Camera::getInstance(), &Camera::resolutionProbingFinished, this, &AVForm::onResProbingFinished); connect(Camera::getInstance(), &Camera::resolutionProbingFinished, this, &AVForm::onResProbingFinished);
auto qcomboboxIndexChanged = (void(QComboBox::*)(const QString&)) &QComboBox::currentIndexChanged; auto qcomboboxIndexChanged = (void(QComboBox::*)(const QString&)) &QComboBox::currentIndexChanged;
connect(bodyUI->inDevCombobox, qcomboboxIndexChanged, this, &AVForm::onInDevChanged); connect(bodyUI->inDevCombobox, qcomboboxIndexChanged, this, &AVForm::onInDevChanged);
connect(bodyUI->outDevCombobox, qcomboboxIndexChanged, this, &AVForm::onOutDevChanged); connect(bodyUI->outDevCombobox, qcomboboxIndexChanged, this, &AVForm::onOutDevChanged);
connect(bodyUI->rescanButton, &QPushButton::clicked, this, [=](){getAudioInDevices(); getAudioOutDevices();});
} }
AVForm::~AVForm() AVForm::~AVForm()
@ -51,6 +49,9 @@ AVForm::~AVForm()
void AVForm::present() void AVForm::present()
{ {
getAudioOutDevices();
getAudioInDevices();
bodyUI->CamVideoSurface->setSource(Camera::getInstance()); bodyUI->CamVideoSurface->setSource(Camera::getInstance());
Camera::getInstance()->probeProp(Camera::SATURATION); Camera::getInstance()->probeProp(Camera::SATURATION);

View File

@ -30,8 +30,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>824</width> <width>810</width>
<height>489</height> <height>496</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_5">
@ -41,54 +41,61 @@
<string>Audio Settings</string> <string>Audio Settings</string>
</property> </property>
<layout class="QFormLayout" name="formLayout_2"> <layout class="QFormLayout" name="formLayout_2">
<item row="6" column="0"> <item row="7" column="0">
<widget class="QLabel" name="microphoneLabel"> <widget class="QLabel" name="microphoneLabel">
<property name="text"> <property name="text">
<string>Microphone</string> <string>Microphone</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="playbackLabel"> <widget class="QLabel" name="playbackLabel">
<property name="text"> <property name="text">
<string>Playback</string> <string>Playback</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QSlider" name="playbackSlider"> <widget class="QSlider" name="playbackSlider">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="7" column="1">
<widget class="QSlider" name="microphoneSlider"> <widget class="QSlider" name="microphoneSlider">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="1" column="0">
<widget class="QLabel" name="outDevLabel"> <widget class="QLabel" name="outDevLabel">
<property name="text"> <property name="text">
<string>Playback device</string> <string>Playback device</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="6" column="0">
<widget class="QLabel" name="inDevLabel"> <widget class="QLabel" name="inDevLabel">
<property name="text"> <property name="text">
<string>Capture device</string> <string>Capture device</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1"> <item row="6" column="1">
<widget class="QComboBox" name="inDevCombobox"/> <widget class="QComboBox" name="inDevCombobox"/>
</item> </item>
<item row="0" column="1"> <item row="1" column="1">
<widget class="QComboBox" name="outDevCombobox"/> <widget class="QComboBox" name="outDevCombobox"/>
</item> </item>
<item row="0" column="1">
<widget class="QPushButton" name="rescanButton">
<property name="text">
<string>Rescan audio devices</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -52,7 +52,7 @@ void TabCompleter::buildCompletionList()
// that section is then used as the completion regex // that section is then used as the completion regex
QRegExp regex(QString("^[-_\\[\\]{}|`^.\\\\]*").append(QRegExp::escape(tabAbbrev)), Qt::CaseInsensitive); QRegExp regex(QString("^[-_\\[\\]{}|`^.\\\\]*").append(QRegExp::escape(tabAbbrev)), Qt::CaseInsensitive);
for(auto name : group->peers.values()) for(auto name : group->getPeerList())
if (regex.indexIn(name) > -1) if (regex.indexIn(name) > -1)
completionMap[name.toLower()] = name; completionMap[name.toLower()] = name;

View File

@ -56,9 +56,9 @@ void FriendWidget::contextMenuEvent(QContextMenuEvent * event)
QAction* copyId = menu.addAction(tr("Copy friend ID","Menu to copy the Tox ID of that friend")); QAction* copyId = menu.addAction(tr("Copy friend ID","Menu to copy the Tox ID of that friend"));
QMap<QAction*, Group*> groupActions; QMap<QAction*, Group*> groupActions;
for (Group* group : GroupList::groupList) for (Group* group : GroupList::getAllGroups())
{ {
QAction* groupAction = inviteMenu->addAction(group->widget->getName()); QAction* groupAction = inviteMenu->addAction(group->getGroupWidget()->getName());
groupActions[groupAction] = group; groupActions[groupAction] = group;
} }
@ -115,7 +115,7 @@ void FriendWidget::contextMenuEvent(QContextMenuEvent * event)
else if (groupActions.contains(selectedItem)) else if (groupActions.contains(selectedItem))
{ {
Group* group = groupActions[selectedItem]; Group* group = groupActions[selectedItem];
Core::getInstance()->groupInviteFriend(friendId, group->groupId); Core::getInstance()->groupInviteFriend(friendId, group->getGroupId());
} }
} }
} }

View File

@ -40,7 +40,7 @@ GroupWidget::GroupWidget(int GroupId, QString Name)
Group* g = GroupList::findGroup(groupId); Group* g = GroupList::findGroup(groupId);
if (g) if (g)
statusMessageLabel->setText(GroupWidget::tr("%1 users in chat").arg(g->peers.size())); statusMessageLabel->setText(GroupWidget::tr("%1 users in chat").arg(g->getPeersCount()));
else else
statusMessageLabel->setText(GroupWidget::tr("0 users in chat")); statusMessageLabel->setText(GroupWidget::tr("0 users in chat"));
@ -51,8 +51,8 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent * event)
{ {
QPoint pos = event->globalPos(); QPoint pos = event->globalPos();
QMenu menu; QMenu menu;
QAction* quitGroup = menu.addAction(tr("Quit group","Menu to quit a groupchat"));
QAction* setAlias = menu.addAction(tr("Set title...")); QAction* setAlias = menu.addAction(tr("Set title..."));
QAction* quitGroup = menu.addAction(tr("Quit group","Menu to quit a groupchat"));
QAction* selectedItem = menu.exec(pos); QAction* selectedItem = menu.exec(pos);
if (selectedItem) if (selectedItem)
@ -68,7 +68,7 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent * event)
nameLabel->fullText(), &ok); nameLabel->fullText(), &ok);
if (ok && alias != nameLabel->fullText()) if (ok && alias != nameLabel->fullText())
emit g->chatForm->groupTitleChanged(groupId, alias.left(128)); emit g->getChatForm()->groupTitleChanged(groupId, alias.left(128));
} }
} }
} }
@ -77,7 +77,7 @@ void GroupWidget::onUserListChanged()
{ {
Group* g = GroupList::findGroup(groupId); Group* g = GroupList::findGroup(groupId);
if (g) if (g)
statusMessageLabel->setText(tr("%1 users in chat").arg(g->nPeers)); statusMessageLabel->setText(tr("%1 users in chat").arg(g->getPeersCount()));
else else
statusMessageLabel->setText(tr("0 users in chat")); statusMessageLabel->setText(tr("0 users in chat"));
} }
@ -98,13 +98,13 @@ void GroupWidget::updateStatusLight()
{ {
Group *g = GroupList::findGroup(groupId); Group *g = GroupList::findGroup(groupId);
if (g->hasNewMessages == 0) if (!g->getEventFlag())
{ {
statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); statusPic.setPixmap(QPixmap(":img/status/dot_online.png"));
} }
else else
{ {
if (g->userWasMentioned == 0) if (!g->getMentionedFlag())
statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png"));
else else
statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png"));
@ -114,14 +114,14 @@ void GroupWidget::updateStatusLight()
void GroupWidget::setChatForm(Ui::MainWindow &ui) void GroupWidget::setChatForm(Ui::MainWindow &ui)
{ {
Group* g = GroupList::findGroup(groupId); Group* g = GroupList::findGroup(groupId);
g->chatForm->show(ui); g->getChatForm()->show(ui);
} }
void GroupWidget::resetEventFlags() void GroupWidget::resetEventFlags()
{ {
Group* g = GroupList::findGroup(groupId); Group* g = GroupList::findGroup(groupId);
g->hasNewMessages = 0; g->setEventFlag(false);
g->userWasMentioned = 0; g->setMentionedFlag(false);
} }
void GroupWidget::dragEnterEvent(QDragEnterEvent *ev) void GroupWidget::dragEnterEvent(QDragEnterEvent *ev)
@ -143,7 +143,7 @@ void GroupWidget::keyPressEvent(QKeyEvent* ev)
{ {
Group* g = GroupList::findGroup(groupId); Group* g = GroupList::findGroup(groupId);
if (g) if (g)
g->chatForm->keyPressEvent(ev); g->getChatForm()->keyPressEvent(ev);
} }
@ -151,7 +151,7 @@ void GroupWidget::keyReleaseEvent(QKeyEvent* ev)
{ {
Group* g = GroupList::findGroup(groupId); Group* g = GroupList::findGroup(groupId);
if (g) if (g)
g->chatForm->keyReleaseEvent(ev); g->getChatForm()->keyReleaseEvent(ev);
} }
void GroupWidget::setName(const QString& name) void GroupWidget::setName(const QString& name)

View File

@ -297,9 +297,7 @@ Widget::~Widget()
delete filesForm; delete filesForm;
FriendList::clear(); FriendList::clear();
for (Group* g : GroupList::groupList) GroupList::clear();
delete g;
GroupList::groupList.clear();
delete trayMenu; delete trayMenu;
delete ui; delete ui;
delete translator; delete translator;
@ -878,7 +876,9 @@ void Widget::clearContactsList()
QList<Friend*> friends = FriendList::getAllFriends(); QList<Friend*> friends = FriendList::getAllFriends();
for (Friend* f : friends) for (Friend* f : friends)
removeFriend(f, true); removeFriend(f, true);
for (Group* g : GroupList::groupList)
QList<Group*> groups = GroupList::getAllGroups();
for (Group* g : groups)
removeGroup(g, true); removeGroup(g, true);
} }
@ -910,29 +910,30 @@ void Widget::onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray in
} }
} }
void Widget::onGroupMessageReceived(int groupnumber, const QString& message, const QString& author, bool isAction) void Widget::onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction)
{ {
Group* g = GroupList::findGroup(groupnumber); Group* g = GroupList::findGroup(groupnumber);
if (!g) if (!g)
return; return;
ToxID author = Core::getInstance()->getGroupPeerToxID(groupnumber, peernumber);
QString name = core->getUsername(); QString name = core->getUsername();
bool targeted = (author != name) && message.contains(name, Qt::CaseInsensitive); bool targeted = (!author.isMine()) && message.contains(name, Qt::CaseInsensitive);
if (targeted) if (targeted)
g->chatForm->addAlertMessage(author, message, QDateTime::currentDateTime()); g->getChatForm()->addAlertMessage(author, message, QDateTime::currentDateTime());
else else
g->chatForm->addMessage(author, message, isAction, QDateTime::currentDateTime()); g->getChatForm()->addMessage(author, message, isAction, QDateTime::currentDateTime(), true);
if ((static_cast<GenericChatroomWidget*>(g->widget) != activeChatroomWidget) || isMinimized() || !isActiveWindow()) if ((static_cast<GenericChatroomWidget*>(g->getGroupWidget()) != activeChatroomWidget) || isMinimized() || !isActiveWindow())
{ {
g->hasNewMessages = 1; g->setEventFlag(true);
if (targeted) if (targeted)
{ {
newMessageAlert(g->widget); newMessageAlert(g->getGroupWidget());
g->userWasMentioned = 1; // useful for highlighting line or desktop notifications g->setMentionedFlag(true); // useful for highlighting line or desktop notifications
} }
g->widget->updateStatusLight(); g->getGroupWidget()->updateStatusLight();
} }
} }
@ -951,14 +952,16 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha
{ {
if (name.isEmpty()) if (name.isEmpty())
name = tr("<Unknown>", "Placeholder when we don't know someone's name in a group chat"); name = tr("<Unknown>", "Placeholder when we don't know someone's name in a group chat");
g->addPeer(peernumber,name); // g->addPeer(peernumber,name);
g->regeneratePeerList();
//g->chatForm->addSystemInfoMessage(tr("%1 has joined the chat").arg(name), "green"); //g->chatForm->addSystemInfoMessage(tr("%1 has joined the chat").arg(name), "green");
// we can't display these messages until irungentoo fixes peernumbers // we can't display these messages until irungentoo fixes peernumbers
// https://github.com/irungentoo/toxcore/issues/1128 // https://github.com/irungentoo/toxcore/issues/1128
} }
else if (change == TOX_CHAT_CHANGE_PEER_DEL) else if (change == TOX_CHAT_CHANGE_PEER_DEL)
{ {
g->removePeer(peernumber); // g->removePeer(peernumber);
g->regeneratePeerList();
//g->chatForm->addSystemInfoMessage(tr("%1 has left the chat").arg(name), "silver"); //g->chatForm->addSystemInfoMessage(tr("%1 has left the chat").arg(name), "silver");
} }
else if (change == TOX_CHAT_CHANGE_PEER_NAME) // core overwrites old name before telling us it changed... else if (change == TOX_CHAT_CHANGE_PEER_NAME) // core overwrites old name before telling us it changed...
@ -973,19 +976,19 @@ void Widget::onGroupTitleChanged(int groupnumber, const QString& author, const Q
g->setName(title); g->setName(title);
if (!author.isEmpty()) if (!author.isEmpty())
g->chatForm->addSystemInfoMessage(tr("%1 has set the title to %2").arg(author, title), "silver", QDateTime::currentDateTime()); g->getChatForm()->addSystemInfoMessage(tr("%1 has set the title to %2").arg(author, title), "silver", QDateTime::currentDateTime());
} }
void Widget::removeGroup(Group* g, bool fake) void Widget::removeGroup(Group* g, bool fake)
{ {
g->widget->setAsInactiveChatroom(); g->getGroupWidget()->setAsInactiveChatroom();
if (static_cast<GenericChatroomWidget*>(g->widget) == activeChatroomWidget) if (static_cast<GenericChatroomWidget*>(g->getGroupWidget()) == activeChatroomWidget)
{ {
activeChatroomWidget = nullptr; activeChatroomWidget = nullptr;
onAddClicked(); onAddClicked();
} }
GroupList::removeGroup(g->groupId, fake); GroupList::removeGroup(g->getGroupId(), fake);
core->removeGroup(g->groupId, fake); core->removeGroup(g->getGroupId(), fake);
delete g; delete g;
if (ui->mainHead->layout()->isEmpty()) if (ui->mainHead->layout()->isEmpty())
onAddClicked(); onAddClicked();
@ -1016,15 +1019,15 @@ Group *Widget::createGroup(int groupId)
QString groupName = QString("Groupchat #%1").arg(groupId); QString groupName = QString("Groupchat #%1").arg(groupId);
Group* newgroup = GroupList::addGroup(groupId, groupName, true); Group* newgroup = GroupList::addGroup(groupId, groupName, true);
QLayout* layout = contactListWidget->getGroupLayout(); QLayout* layout = contactListWidget->getGroupLayout();
layout->addWidget(newgroup->widget); layout->addWidget(newgroup->getGroupWidget());
newgroup->widget->updateStatusLight(); newgroup->getGroupWidget()->updateStatusLight();
connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*))); connect(newgroup->getGroupWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
connect(newgroup->widget, SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int))); connect(newgroup->getGroupWidget(), SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int)));
connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), newgroup->chatForm, SLOT(focusInput())); connect(newgroup->getGroupWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), newgroup->getChatForm(), SLOT(focusInput()));
connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString))); connect(newgroup->getChatForm(), SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString)));
connect(newgroup->chatForm, SIGNAL(sendAction(int,QString)), core, SLOT(sendGroupAction(int,QString))); connect(newgroup->getChatForm(), SIGNAL(sendAction(int,QString)), core, SLOT(sendGroupAction(int,QString)));
connect(newgroup->chatForm, &GroupChatForm::groupTitleChanged, core, &Core::changeGroupTitle); connect(newgroup->getChatForm(), &GroupChatForm::groupTitleChanged, core, &Core::changeGroupTitle);
return newgroup; return newgroup;
} }
@ -1122,7 +1125,7 @@ void Widget::onGroupSendResult(int groupId, const QString& message, int result)
return; return;
if (result == -1) if (result == -1)
g->chatForm->addSystemInfoMessage(tr("Message failed to send"), "red", QDateTime::currentDateTime()); g->getChatForm()->addSystemInfoMessage(tr("Message failed to send"), "red", QDateTime::currentDateTime());
} }
void Widget::getPassword(QString info, int passtype, uint8_t* salt) void Widget::getPassword(QString info, int passtype, uint8_t* salt)
@ -1213,6 +1216,6 @@ void Widget::reloadTheme()
for (Friend* f : FriendList::getAllFriends()) for (Friend* f : FriendList::getAllFriends())
f->getFriendWidget()->reloadTheme(); f->getFriendWidget()->reloadTheme();
for (Group* g : GroupList::groupList) for (Group* g : GroupList::getAllGroups())
g->widget->reloadTheme(); g->getGroupWidget()->reloadTheme();
} }

View File

@ -116,7 +116,7 @@ private slots:
void onReceiptRecieved(int friendId, int receipt); void onReceiptRecieved(int friendId, int receipt);
void onEmptyGroupCreated(int groupId); void onEmptyGroupCreated(int groupId);
void onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray invite); void onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray invite);
void onGroupMessageReceived(int groupnumber, const QString& message, const QString& author, bool isAction); void onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction);
void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change); void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
void onGroupTitleChanged(int groupnumber, const QString& author, const QString& title); void onGroupTitleChanged(int groupnumber, const QString& author, const QString& title);
void removeFriend(int friendId); void removeFriend(int friendId);