From 50a3962e4d0b16fd0316be54121cfb293c3117bd Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Thu, 1 Oct 2015 11:09:04 +0100 Subject: Ignore DND drops of JIDs for contacts already in the conversation Swift allows dropping contacts from group chats or the roster on a chat window to invite them or start an impromptu chat. With this commit Swift will ignore drops which only contain JIDs that are already part of the conversation. Test-Information: Tested the described behavior with roster and room contact drags in anonymous and non-anonymous rooms. Change-Id: I2f06082ea4bc1140210f9f1a165bdf276a130273 diff --git a/Swift/Controllers/Roster/Roster.cpp b/Swift/Controllers/Roster/Roster.cpp index 84561e5..77d6b78 100644 --- a/Swift/Controllers/Roster/Roster.cpp +++ b/Swift/Controllers/Roster/Roster.cpp @@ -51,6 +51,28 @@ GroupRosterItem* Roster::getRoot() const { return root_; } +std::set Roster::getJIDs() const { + std::set jids; + + std::deque queue; + queue.push_back(root_); + while (!queue.empty()) { + RosterItem* item = *queue.begin(); + queue.pop_front(); + GroupRosterItem* group = dynamic_cast(item); + ContactRosterItem *contact = dynamic_cast(item); + if (contact) { + jids.insert(contact->getJID()); + jids.insert(contact->getDisplayJID()); + } + else if (group) { + queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); + } + } + + return jids; +} + GroupRosterItem* Roster::getGroup(const std::string& groupName) { foreach (RosterItem *item, root_->getChildren()) { GroupRosterItem *group = dynamic_cast(item); diff --git a/Swift/Controllers/Roster/Roster.h b/Swift/Controllers/Roster/Roster.h index c25feaa..269ec4d 100644 --- a/Swift/Controllers/Roster/Roster.h +++ b/Swift/Controllers/Roster/Roster.h @@ -42,6 +42,8 @@ class Roster { void addFilter(RosterFilter* filter); void removeFilter(RosterFilter* filter); GroupRosterItem* getRoot() const; + std::set getJIDs() const; + std::vector getFilters() {return filters_;} boost::signal onChildrenChanged; boost::signal onGroupAdded; diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index d58393b..abbfae5 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -597,7 +597,29 @@ void QtChatWindow::dragEnterEvent(QDragEnterEvent *event) { } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { if (isMUC_ || supportsImpromptuChat_) { - event->acceptProposedAction(); + // Prevent invitations or impromptu initializations for contacts that you are already chatting to. + std::vector droppedJIDs =jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list")); + std::set conversationJIDs; + if (isMUC_) { + conversationJIDs = treeWidget_->getRoster()->getJIDs(); + } + + for (std::vector::iterator i = droppedJIDs.begin(); i != droppedJIDs.end(); ) { + const JID& droppedJID = *i; + if (conversationJIDs.find(droppedJID) != conversationJIDs.end()) { + i = droppedJIDs.erase(i); + } + else { + ++i; + } + } + + if (droppedJIDs.empty()) { + event->ignore(); + } + else { + event->acceptProposedAction(); + } } } } @@ -616,18 +638,22 @@ void QtChatWindow::dropEvent(QDropEvent *event) { } } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { - QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid-list"); - QDataStream dataStream(&dataBytes, QIODevice::ReadOnly); - std::vector invites; - while (!dataStream.atEnd()) { - QString jidString; - dataStream >> jidString; - invites.push_back(Q2PSTRING(jidString)); - } + std::vector invites = jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list")); onInviteToChat(invites); } } +std::vector QtChatWindow::jidListFromQByteArray(const QByteArray& dataBytes) { + QDataStream dataStream(dataBytes); + std::vector invites; + while (!dataStream.atEnd()) { + QString jidString; + dataStream >> jidString; + invites.push_back(Q2PSTRING(jidString)); + } + return invites; +} + void QtChatWindow::setAvailableOccupantActions(const std::vector& actions) { treeWidget_->setAvailableOccupantActions(actions); } diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 8d7db59..bbcdee7 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -185,6 +185,8 @@ namespace Swift { void handleOccupantSelectionChanged(RosterItem* item); void handleAppendedToLog(); + static std::vector jidListFromQByteArray(const QByteArray& dataBytes); + private: int unreadCount_; bool contactIsTyping_; -- cgit v0.10.2-6-g49f6