From 415d56ba697f20360d54e380f5c8d326a6fb288b Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 28 Sep 2019 17:30:16 +0300 Subject: [PATCH] Disabled context menu on items of not connected account, roster contacts group moving, bugfixes with roster contacts group moving ungrouping and copying --- core/account.cpp | 47 +++++++++++ core/account.h | 2 + core/squawk.cpp | 20 +++++ core/squawk.h | 2 + global.cpp | 2 +- main.cpp | 2 + ui/models/abstractparticipant.cpp | 9 ++ ui/models/abstractparticipant.h | 1 + ui/models/contact.cpp | 25 ++++++ ui/models/contact.h | 3 + ui/models/group.cpp | 13 +++ ui/models/group.h | 2 + ui/models/item.cpp | 27 ++++++ ui/models/item.h | 5 ++ ui/models/presence.cpp | 7 ++ ui/models/presence.h | 1 + ui/models/roster.cpp | 131 ++++++++++++++++++++++-------- ui/models/roster.h | 3 + ui/squawk.cpp | 46 +++++++++++ ui/squawk.h | 2 + 20 files changed, 314 insertions(+), 36 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index 68c547f..a46ea8f 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -1153,3 +1153,50 @@ void Core::Account::addNewRoom(const QString& jid, const QString& nick, const QS {"name", conf->getName()} }); } + +void Core::Account::addContactToGroupRequest(const QString& jid, const QString& groupName) +{ + std::map::const_iterator itr = contacts.find(jid); + if (itr == contacts.end()) { + qDebug() << "An attempt to add non existing contact" << jid << "of account" << name << "to the group" << groupName << ", skipping"; + } else { + QXmppRosterManager& rm = client.rosterManager(); + QXmppRosterIq::Item item = rm.getRosterEntry(jid); + QSet groups = item.groups(); + if (groups.find(groupName) == groups.end()) { //TODO need to change it, I guess that sort of code is better in qxmpp lib + groups.insert(groupName); + item.setGroups(groups); + + QXmppRosterIq iq; + iq.setType(QXmppIq::Set); + iq.addItem(item); + client.sendPacket(iq); + } else { + qDebug() << "An attempt to add contact" << jid << "of account" << name << "to the group" << groupName << "but it's already in that group, skipping"; + } + } +} + +void Core::Account::removeContactFromGroupRequest(const QString& jid, const QString& groupName) +{ + std::map::const_iterator itr = contacts.find(jid); + if (itr == contacts.end()) { + qDebug() << "An attempt to remove non existing contact" << jid << "of account" << name << "from the group" << groupName << ", skipping"; + } else { + QXmppRosterManager& rm = client.rosterManager(); + QXmppRosterIq::Item item = rm.getRosterEntry(jid); + QSet groups = item.groups(); + QSet::const_iterator gItr = groups.find(groupName); + if (gItr != groups.end()) { + groups.erase(gItr); + item.setGroups(groups); + + QXmppRosterIq iq; + iq.setType(QXmppIq::Set); + iq.addItem(item); + client.sendPacket(iq); + } else { + qDebug() << "An attempt to remove contact" << jid << "of account" << name << "from the group" << groupName << "but it's not in that group, skipping"; + } + } +} diff --git a/core/account.h b/core/account.h index 2dda75c..839af23 100644 --- a/core/account.h +++ b/core/account.h @@ -70,6 +70,8 @@ public: void unsubscribeFromContact(const QString& jid, const QString& reason); void removeContactRequest(const QString& jid); void addContactRequest(const QString& jid, const QString& name, const QSet& groups); + void addContactToGroupRequest(const QString& jid, const QString& groupName); + void removeContactFromGroupRequest(const QString& jid, const QString& groupName); void setRoomJoined(const QString& jid, bool joined); void setRoomAutoJoin(const QString& jid, bool joined); diff --git a/core/squawk.cpp b/core/squawk.cpp index bf9550f..181a991 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -498,3 +498,23 @@ void Core::Squawk::downloadFileRequest(const QString& messageId, const QString& { network.downladFileRequest(messageId, url); } + +void Core::Squawk::addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName) +{ + AccountsMap::const_iterator itr = amap.find(account); + if (itr == amap.end()) { + qDebug() << "An attempt to add contact" << jid << "of existing account" << account << "to the group" << groupName << ", skipping"; + return; + } + itr->second->addContactToGroupRequest(jid, groupName); +} + +void Core::Squawk::removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName) +{ + AccountsMap::const_iterator itr = amap.find(account); + if (itr == amap.end()) { + qDebug() << "An attempt to add contact" << jid << "of existing account" << account << "to the group" << groupName << ", skipping"; + return; + } + itr->second->removeContactFromGroupRequest(jid, groupName); +} diff --git a/core/squawk.h b/core/squawk.h index 89f4c2d..1e4980b 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -79,6 +79,8 @@ public slots: void requestArchive(const QString& account, const QString& jid, int count, const QString& before); void subscribeContact(const QString& account, const QString& jid, const QString& reason); void unsubscribeContact(const QString& account, const QString& jid, const QString& reason); + void addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName); + void removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName); void removeContactRequest(const QString& account, const QString& jid); void addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet& groups); void setRoomJoined(const QString& account, const QString& jid, bool joined); diff --git a/global.cpp b/global.cpp index 1561983..8ab74d8 100644 --- a/global.cpp +++ b/global.cpp @@ -350,6 +350,6 @@ QIcon Shared::icon(const QString& name, bool big) return QIcon::fromTheme(itr->second.first, QIcon(prefix + itr->second.second)); } else { qDebug() << "Icon" << name << "not found"; - throw 1; + return QIcon::fromTheme(name); } } diff --git a/main.cpp b/main.cpp index d0fba26..8d612a5 100644 --- a/main.cpp +++ b/main.cpp @@ -89,6 +89,8 @@ int main(int argc, char *argv[]) squawk, SLOT(addRoomRequest(const QString&, const QString&, const QString&, const QString&, bool))); QObject::connect(&w, SIGNAL(fileLocalPathRequest(const QString&, const QString&)), squawk, SLOT(fileLocalPathRequest(const QString&, const QString&))); QObject::connect(&w, SIGNAL(downloadFileRequest(const QString&, const QString&)), squawk, SLOT(downloadFileRequest(const QString&, const QString&))); + QObject::connect(&w, &Squawk::addContactToGroupRequest, squawk, &Core::Squawk::addContactToGroupRequest); + QObject::connect(&w, &Squawk::removeContactFromGroupRequest, squawk, &Core::Squawk::removeContactFromGroupRequest); QObject::connect(squawk, SIGNAL(newAccount(const QMap&)), &w, SLOT(newAccount(const QMap&))); QObject::connect(squawk, SIGNAL(addContact(const QString&, const QString&, const QString&, const QMap&)), diff --git a/ui/models/abstractparticipant.cpp b/ui/models/abstractparticipant.cpp index 7fef30a..53d8b2d 100644 --- a/ui/models/abstractparticipant.cpp +++ b/ui/models/abstractparticipant.cpp @@ -32,6 +32,15 @@ Models::AbstractParticipant::AbstractParticipant(Models::Item::Type p_type, cons } } +Models::AbstractParticipant::AbstractParticipant(const Models::AbstractParticipant& other): + Item(other), + availability(other.availability), + lastActivity(other.lastActivity), + status(other.status) +{ +} + + Models::AbstractParticipant::~AbstractParticipant() { } diff --git a/ui/models/abstractparticipant.h b/ui/models/abstractparticipant.h index 44cbcb9..86d5629 100644 --- a/ui/models/abstractparticipant.h +++ b/ui/models/abstractparticipant.h @@ -31,6 +31,7 @@ class AbstractParticipant : public Models::Item Q_OBJECT public: explicit AbstractParticipant(Type p_type, const QMap &data, Item *parentItem = 0); + AbstractParticipant(const AbstractParticipant& other); ~AbstractParticipant(); virtual int columnCount() const override; diff --git a/ui/models/contact.cpp b/ui/models/contact.cpp index 5248eb2..5f4ba21 100644 --- a/ui/models/contact.cpp +++ b/ui/models/contact.cpp @@ -323,3 +323,28 @@ bool Models::Contact::columnInvolvedInDisplay(int col) { return Item::columnInvolvedInDisplay(col) && col == 1; } + +Models::Contact * Models::Contact::copy() const +{ + Contact* cnt = new Contact(*this); + return cnt; +} + +Models::Contact::Contact(const Models::Contact& other): + Item(other), + jid(other.jid), + availability(other.availability), + state(other.state), + presences(), + messages(other.messages), + childMessages(0) +{ + for (const Presence* pres : other.presences) { + Presence* pCopy = new Presence(*pres); + presences.insert(pCopy->getName(), pCopy); + Item::appendChild(pCopy); + connect(pCopy, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(refresh())); + } + + refresh(); +} diff --git a/ui/models/contact.h b/ui/models/contact.h index 835f7b7..6f0a5fc 100644 --- a/ui/models/contact.h +++ b/ui/models/contact.h @@ -34,6 +34,7 @@ class Contact : public Item public: typedef std::deque Messages; Contact(const QString& p_jid, const QMap &data, Item *parentItem = 0); + Contact(const Contact& other); ~Contact(); QString getJid() const; @@ -59,6 +60,8 @@ public: void getMessages(Messages& container) const; QString getDisplayedName() const override; + Contact* copy() const; + protected: void _removeChild(int index) override; bool columnInvolvedInDisplay(int col) override; diff --git a/ui/models/group.cpp b/ui/models/group.cpp index 1880714..d857710 100644 --- a/ui/models/group.cpp +++ b/ui/models/group.cpp @@ -103,3 +103,16 @@ unsigned int Models::Group::getOnlineContacts() const return amount; } + +bool Models::Group::hasContact(const QString& jid) const +{ + for (Models::Item* item : childItems) { + if (item->type == Item::contact) { + const Contact* cnt = static_cast(item); + if (cnt->getJid() == jid) { + return true; + } + } + } + return false; +} diff --git a/ui/models/group.h b/ui/models/group.h index 8301dc8..c2f4bfe 100644 --- a/ui/models/group.h +++ b/ui/models/group.h @@ -36,6 +36,8 @@ public: unsigned int getUnreadMessages() const; unsigned int getOnlineContacts() const; + + bool hasContact(const QString& jid) const; protected: void _removeChild(int index) override; diff --git a/ui/models/item.cpp b/ui/models/item.cpp index db99a11..7c0cb96 100644 --- a/ui/models/item.cpp +++ b/ui/models/item.cpp @@ -34,6 +34,15 @@ Models::Item::Item(Type p_type, const QMap &p_data, Item *p_p } } +Models::Item::Item(const Models::Item& other): + QObject(), + type(other.type), + name(other.name), + childItems(), + parent(nullptr) +{ +} + Models::Item::~Item() { std::deque::const_iterator itr = childItems.begin(); @@ -225,6 +234,24 @@ QString Models::Item::getAccountName() const return acc->getName(); } +Shared::Availability Models::Item::getAccountAvailability() const +{ + const Account* acc = static_cast(getParentAccount()); + if (acc == 0) { + return Shared::offline; + } + return acc->getAvailability(); +} + +Shared::ConnectionState Models::Item::getAccountConnectionState() const +{ + const Account* acc = static_cast(getParentAccount()); + if (acc == 0) { + return Shared::disconnected; + } + return acc->getState(); +} + QString Models::Item::getDisplayedName() const { return name; diff --git a/ui/models/item.h b/ui/models/item.h index d9d8286..20f6f89 100644 --- a/ui/models/item.h +++ b/ui/models/item.h @@ -25,6 +25,8 @@ #include +#include "../../global.h" + namespace Models { class Item : public QObject{ @@ -41,6 +43,7 @@ class Item : public QObject{ }; explicit Item(Type p_type, const QMap &data, Item *parentItem = 0); + Item(const Item& other); ~Item(); signals: @@ -71,6 +74,8 @@ class Item : public QObject{ QString getAccountName() const; QString getAccountJid() const; QString getAccountResource() const; + Shared::ConnectionState getAccountConnectionState() const; + Shared::Availability getAccountAvailability() const; const Type type; diff --git a/ui/models/presence.cpp b/ui/models/presence.cpp index b6be0fe..36b07d2 100644 --- a/ui/models/presence.cpp +++ b/ui/models/presence.cpp @@ -24,6 +24,13 @@ Models::Presence::Presence(const QMap& data, Item* parentItem { } +Models::Presence::Presence(const Models::Presence& other): + AbstractParticipant(other), + messages(other.messages) +{ +} + + Models::Presence::~Presence() { } diff --git a/ui/models/presence.h b/ui/models/presence.h index c396f0c..8371be7 100644 --- a/ui/models/presence.h +++ b/ui/models/presence.h @@ -32,6 +32,7 @@ class Presence : public Models::AbstractParticipant public: typedef std::deque Messages; explicit Presence(const QMap &data, Item *parentItem = 0); + Presence(const Presence& other); ~Presence(); int columnCount() const override; diff --git a/ui/models/roster.cpp b/ui/models/roster.cpp index 6c37645..79b0d03 100644 --- a/ui/models/roster.cpp +++ b/ui/models/roster.cpp @@ -383,50 +383,52 @@ void Models::Roster::addContact(const QString& account, const QString& jid, cons { Item* parent; Account* acc; - Contact* contact; + Contact* sample = 0; ElId id(account, jid); { std::map::iterator itr = accounts.find(account); if (itr == accounts.end()) { - qDebug() << "An attempt to add a contact " << jid << " to non existing account " << account << ", skipping"; + qDebug() << "An attempt to add a contact" << jid << "to non existing account" << account << ", skipping"; return; } acc = itr->second; } - if (group == "") { - std::multimap::iterator itr = contacts.lower_bound(id); - std::multimap::iterator eItr = contacts.upper_bound(id); - while (itr != eItr) { - if (itr->second->parentItem() == acc) { - qDebug() << "An attempt to add a contact " << jid << " ungrouped to non the account " << account << " for the second time, skipping"; - return; - } - itr++; + for (std::multimap::iterator itr = contacts.lower_bound(id), eItr = contacts.upper_bound(id); itr != eItr; ++itr) { + sample = itr->second; //need to find if this contact is already added somewhere + break; //so one iteration is enough + } + + if (group == "") { //this means this contact is already added somewhere and there is no sense to add it ungrouped + if (sample != 0) { + qDebug() << "An attempt to add a contact" << jid << "to the ungrouped contact set of account" << account << "for the second time, skipping"; + return; + } else { + parent = acc; } - parent = acc; } else { std::map::iterator itr = groups.find({account, group}); if (itr == groups.end()) { - qDebug() << "An attempt to add a contact " << jid << " to non existing group " << group << ", skipping"; - return; + qDebug() << "An attempt to add a contact" << jid << "to non existing group" << group << ", adding group"; + addGroup(account, group); + itr = groups.find({account, group}); } parent = itr->second; - for (int i = 0; i < parent->childCount(); ++i) { + for (int i = 0; i < parent->childCount(); ++i) { //checking if the contact is already added to that group Item* item = parent->child(i); if (item->type == Item::contact) { Contact* ca = static_cast(item); if (ca->getJid() == jid) { - qDebug() << "An attempt to add a contact " << jid << " to the group " << group << " for the second time, skipping"; + qDebug() << "An attempt to add a contact" << jid << "to the group" << group << "for the second time, skipping"; return; } } } - for (int i = 0; i < acc->childCount(); ++i) { + for (int i = 0; i < acc->childCount(); ++i) { //checking if that contact is among ugrouped Item* item = acc->child(i); if (item->type == Item::contact) { Contact* ca = static_cast(item); @@ -440,7 +442,12 @@ void Models::Roster::addContact(const QString& account, const QString& jid, cons } } - contact = new Contact(jid, data); + Contact* contact; + if (sample == 0) { + contact = new Contact(jid, data); + } else { + contact = sample->copy(); + } contacts.insert(std::make_pair(id, contact)); parent->appendChild(contact); } @@ -548,29 +555,59 @@ void Models::Roster::removeContact(const QString& account, const QString& jid, c qDebug() << "An attempt to remove contact " << jid << " from non existing group " << group << " of account " << account <<", skipping"; return; } + Account* acc = accounts.find(account)->second; //I assume the account is found, otherwise there will be no groups with that ElId; Group* gr = gItr->second; Contact* cont = 0; - std::multimap::iterator cBeg = contacts.lower_bound(contactId); - std::multimap::iterator cEnd = contacts.upper_bound(contactId); - for (;cBeg != cEnd; ++cBeg) { - if (cBeg->second->parentItem() == gr) { - cont = cBeg->second; - contacts.erase(cBeg); - break; + unsigned int entries(0); + unsigned int ungroupped(0); + for (std::multimap::iterator cBeg = contacts.lower_bound(contactId), cEnd = contacts.upper_bound(contactId); cBeg != cEnd; ++cBeg) { + ++entries; + Contact* elem = cBeg->second; + if (elem->parentItem() == acc) { + ++ungroupped; } } - if (cont == 0) { - qDebug() << "An attempt to remove contact " << jid << " of account " << account << " from group " << group <<", but there is no such contact in that group, skipping"; - return; - } - - gr->removeChild(cont->row()); - cont->deleteLater(); - - if (gr->childCount() == 0) { - removeGroup(account, group); + if (ungroupped == 0 && entries == 1) { + for (std::multimap::iterator cBeg = contacts.lower_bound(contactId), cEnd = contacts.upper_bound(contactId); cBeg != cEnd; ++cBeg) { + if (cBeg->second->parentItem() == gr) { + cont = cBeg->second; + break; + } + } + + if (cont == 0) { + qDebug() << "An attempt to remove contact " << jid << " of account " << account << " from group " << group <<", but there is no such contact in that group, skipping"; + return; + } + + qDebug() << "An attempt to remove last instance of contact" << jid << "from the group" << group << ", contact will be moved to ungrouped contacts of" << account; + acc->appendChild(cont); + + if (gr->childCount() == 0) { + removeGroup(account, group); + } + } else { + for (std::multimap::iterator cBeg = contacts.lower_bound(contactId), cEnd = contacts.upper_bound(contactId); cBeg != cEnd; ++cBeg) { + if (cBeg->second->parentItem() == gr) { + cont = cBeg->second; + contacts.erase(cBeg); + break; + } + } + + if (cont == 0) { + qDebug() << "An attempt to remove contact" << jid << "of account" << account << "from group" << group <<", but there is no such contact in that group, skipping"; + return; + } + + gr->removeChild(cont->row()); + cont->deleteLater(); + + if (gr->childCount() == 0) { + removeGroup(account, group); + } } } @@ -844,3 +881,27 @@ void Models::Roster::removeRoomParticipant(const QString& account, const QString itr->second->removeParticipant(name); } } + +std::deque Models::Roster::groupList(const QString& account) const +{ + std::deque answer; + for (std::pair pair : groups) { + if (pair.first.account == account) { + answer.push_back(pair.first.name); + } + } + + return answer; +} + +bool Models::Roster::groupHasContact(const QString& account, const QString& group, const QString& contact) const +{ + ElId grId({account, group}); + std::map::const_iterator gItr = groups.find(grId); + if (gItr == groups.end()) { + return false; + } else { + const Group* gr = gItr->second; + return gr->hasContact(contact); + } +} diff --git a/ui/models/roster.h b/ui/models/roster.h index 314e92d..30fb884 100644 --- a/ui/models/roster.h +++ b/ui/models/roster.h @@ -71,6 +71,9 @@ public: QModelIndex parent ( const QModelIndex& child ) const override; QModelIndex index ( int row, int column, const QModelIndex& parent ) const override; + std::deque groupList(const QString& account) const; + bool groupHasContact(const QString& account, const QString& group, const QString& contactJID) const; + Accounts* accountsModel; private: diff --git a/ui/squawk.cpp b/ui/squawk.cpp index f30a8bb..b05caa7 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -20,6 +20,7 @@ #include "ui_squawk.h" #include #include +#include Squawk::Squawk(QWidget *parent) : QMainWindow(parent), @@ -517,6 +518,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) contextMenu->clear(); bool hasMenu = false; + bool active = item->getAccountConnectionState() == Shared::connected; switch (item->type) { case Models::Item::account: { Models::Account* acc = static_cast(item); @@ -525,17 +527,20 @@ void Squawk::onRosterContextMenu(const QPoint& point) if (acc->getState() != Shared::disconnected) { QAction* con = contextMenu->addAction(Shared::icon("network-disconnect"), "Disconnect"); + con->setEnabled(active); connect(con, &QAction::triggered, [this, name]() { emit disconnectAccount(name); }); } else { QAction* con = contextMenu->addAction(Shared::icon("network-connect"), "Connect"); + con->setEnabled(active); connect(con, &QAction::triggered, [this, name]() { emit connectAccount(name); }); } QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), "Remove"); + remove->setEnabled(active); connect(remove, &QAction::triggered, [this, name]() { emit removeAccount(name); }); @@ -547,6 +552,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) hasMenu = true; QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), "Open dialog"); + dialog->setEnabled(active); connect(dialog, &QAction::triggered, [this, index]() { onRosterItemDoubleClicked(index); }); @@ -556,6 +562,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) case Shared::both: case Shared::to: { QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), "Unsubscribe"); + unsub->setEnabled(active); connect(unsub, &QAction::triggered, [this, cnt]() { emit unsubscribeContact(cnt->getAccountName(), cnt->getJid(), ""); }); @@ -565,13 +572,48 @@ void Squawk::onRosterContextMenu(const QPoint& point) case Shared::unknown: case Shared::none: { QAction* sub = contextMenu->addAction(Shared::icon("news-subscribe"), "Subscribe"); + sub->setEnabled(active); connect(sub, &QAction::triggered, [this, cnt]() { emit subscribeContact(cnt->getAccountName(), cnt->getJid(), ""); }); } } + QMenu* groupsMenu = contextMenu->addMenu(Shared::icon("group"), "Groups"); + QString accName = cnt->getAccountName(); + QString cntJID = cnt->getJid(); + std::deque groupList = rosterModel.groupList(accName); + for (QString groupName : groupList) { + QAction* gr = groupsMenu->addAction(groupName); + gr->setCheckable(true); + gr->setChecked(rosterModel.groupHasContact(accName, groupName, cntJID)); + gr->setEnabled(active); + connect(gr, &QAction::toggled, [this, accName, groupName, cntJID](bool checked) { + if (checked) { + emit addContactToGroupRequest(accName, cntJID, groupName); + } else { + emit removeContactFromGroupRequest(accName, cntJID, groupName); + } + }); + } + QAction* newGroup = groupsMenu->addAction(Shared::icon("resource-group-new"), "New group"); + newGroup->setEnabled(active); + connect(newGroup, &QAction::triggered, [this, accName, cntJID]() { + QInputDialog* dialog = new QInputDialog(this); + connect(dialog, &QDialog::accepted, [this, dialog, accName, cntJID]() { + emit addContactToGroupRequest(accName, cntJID, dialog->textValue()); + dialog->deleteLater(); + }); + connect(dialog, &QDialog::rejected, dialog, &QObject::deleteLater); + dialog->setInputMode(QInputDialog::TextInput); + dialog->setLabelText("New group name"); + dialog->setWindowTitle("Add " + cntJID + " to a new group"); + dialog->exec(); + }); + + QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), "Remove"); + remove->setEnabled(active); connect(remove, &QAction::triggered, [this, cnt]() { emit removeContactRequest(cnt->getAccountName(), cnt->getJid()); }); @@ -583,6 +625,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) hasMenu = true; QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), "Open conversation"); + dialog->setEnabled(active); connect(dialog, &QAction::triggered, [this, index]() { onRosterItemDoubleClicked(index); }); @@ -591,6 +634,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) Models::Roster::ElId id(room->getAccountName(), room->getJid()); if (room->getAutoJoin()) { QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), "Unsubscribe"); + unsub->setEnabled(active); connect(unsub, &QAction::triggered, [this, id]() { emit setRoomAutoJoin(id.account, id.name, false); if (conversations.find(id) == conversations.end()) { //to leave the room if it's not opened in a conversation window @@ -599,6 +643,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) }); } else { QAction* unsub = contextMenu->addAction(Shared::icon("news-subscribe"), "Subscribe"); + unsub->setEnabled(active); connect(unsub, &QAction::triggered, [this, id]() { emit setRoomAutoJoin(id.account, id.name, true); if (conversations.find(id) == conversations.end()) { //to join the room if it's not already joined @@ -608,6 +653,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) } QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), "Remove"); + remove->setEnabled(active); connect(remove, &QAction::triggered, [this, id]() { emit removeRoomRequest(id.account, id.name); }); diff --git a/ui/squawk.h b/ui/squawk.h index 99a6be7..1991646 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -62,6 +62,8 @@ signals: void unsubscribeContact(const QString& account, const QString& jid, const QString& reason); void removeContactRequest(const QString& account, const QString& jid); void addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet& groups); + void addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName); + void removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName); void setRoomJoined(const QString& account, const QString& jid, bool joined); void setRoomAutoJoin(const QString& account, const QString& jid, bool joined); void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin);