diff options
| author | Tobias Markmann <tm@ayena.de> | 2015-10-01 10:09:04 (GMT) |
|---|---|---|
| committer | Kevin Smith <kevin.smith@isode.com> | 2015-10-30 14:23:56 (GMT) |
| commit | 50a3962e4d0b16fd0316be54121cfb293c3117bd (patch) | |
| tree | dc85f9fd75c14542f5f1f00a3878891400ef2f41 | |
| parent | 3a153509d27882e29456ffc7bf67d9cf32d86d52 (diff) | |
| download | swift-50a3962e4d0b16fd0316be54121cfb293c3117bd.zip swift-50a3962e4d0b16fd0316be54121cfb293c3117bd.tar.bz2 | |
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
| -rw-r--r-- | Swift/Controllers/Roster/Roster.cpp | 22 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/Roster.h | 2 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 44 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.h | 2 |
4 files changed, 61 insertions, 9 deletions
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 | |||
| @@ -49,10 +49,32 @@ Roster::~Roster() { | |||
| 49 | 49 | ||
| 50 | GroupRosterItem* Roster::getRoot() const { | 50 | GroupRosterItem* Roster::getRoot() const { |
| 51 | return root_; | 51 | return root_; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | std::set<JID> Roster::getJIDs() const { | ||
| 55 | std::set<JID> jids; | ||
| 56 | |||
| 57 | std::deque<RosterItem*> queue; | ||
| 58 | queue.push_back(root_); | ||
| 59 | while (!queue.empty()) { | ||
| 60 | RosterItem* item = *queue.begin(); | ||
| 61 | queue.pop_front(); | ||
| 62 | GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); | ||
| 63 | ContactRosterItem *contact = dynamic_cast<ContactRosterItem*>(item); | ||
| 64 | if (contact) { | ||
| 65 | jids.insert(contact->getJID()); | ||
| 66 | jids.insert(contact->getDisplayJID()); | ||
| 67 | } | ||
| 68 | else if (group) { | ||
| 69 | queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | return jids; | ||
| 74 | } | ||
| 75 | |||
| 54 | GroupRosterItem* Roster::getGroup(const std::string& groupName) { | 76 | GroupRosterItem* Roster::getGroup(const std::string& groupName) { |
| 55 | foreach (RosterItem *item, root_->getChildren()) { | 77 | foreach (RosterItem *item, root_->getChildren()) { |
| 56 | GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item); | 78 | GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item); |
| 57 | if (group && group->getDisplayName() == groupName) { | 79 | if (group && group->getDisplayName() == groupName) { |
| 58 | return group; | 80 | return group; |
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 | |||
| @@ -40,10 +40,12 @@ class Roster { | |||
| 40 | void applyOnAllItems(const RosterItemOperation& operation); | 40 | void applyOnAllItems(const RosterItemOperation& operation); |
| 41 | void applyOnItem(const RosterItemOperation& operation, const JID& jid); | 41 | void applyOnItem(const RosterItemOperation& operation, const JID& jid); |
| 42 | void addFilter(RosterFilter* filter); | 42 | void addFilter(RosterFilter* filter); |
| 43 | void removeFilter(RosterFilter* filter); | 43 | void removeFilter(RosterFilter* filter); |
| 44 | GroupRosterItem* getRoot() const; | 44 | GroupRosterItem* getRoot() const; |
| 45 | std::set<JID> getJIDs() const; | ||
| 46 | |||
| 45 | std::vector<RosterFilter*> getFilters() {return filters_;} | 47 | std::vector<RosterFilter*> getFilters() {return filters_;} |
| 46 | boost::signal<void (GroupRosterItem*)> onChildrenChanged; | 48 | boost::signal<void (GroupRosterItem*)> onChildrenChanged; |
| 47 | boost::signal<void (GroupRosterItem*)> onGroupAdded; | 49 | boost::signal<void (GroupRosterItem*)> onGroupAdded; |
| 48 | boost::signal<void (RosterItem*)> onDataChanged; | 50 | boost::signal<void (RosterItem*)> onDataChanged; |
| 49 | boost::signal<void (JID&)> onVCardUpdateRequested; | 51 | boost::signal<void (JID&)> onVCardUpdateRequested; |
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 | |||
| @@ -595,11 +595,33 @@ void QtChatWindow::dragEnterEvent(QDragEnterEvent *event) { | |||
| 595 | event->acceptProposedAction(); | 595 | event->acceptProposedAction(); |
| 596 | } | 596 | } |
| 597 | } | 597 | } |
| 598 | else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { | 598 | else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { |
| 599 | if (isMUC_ || supportsImpromptuChat_) { | 599 | if (isMUC_ || supportsImpromptuChat_) { |
| 600 | event->acceptProposedAction(); | 600 | // Prevent invitations or impromptu initializations for contacts that you are already chatting to. |
| 601 | std::vector<JID> droppedJIDs =jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list")); | ||
| 602 | std::set<JID> conversationJIDs; | ||
| 603 | if (isMUC_) { | ||
| 604 | conversationJIDs = treeWidget_->getRoster()->getJIDs(); | ||
| 605 | } | ||
| 606 | |||
| 607 | for (std::vector<JID>::iterator i = droppedJIDs.begin(); i != droppedJIDs.end(); ) { | ||
| 608 | const JID& droppedJID = *i; | ||
| 609 | if (conversationJIDs.find(droppedJID) != conversationJIDs.end()) { | ||
| 610 | i = droppedJIDs.erase(i); | ||
| 611 | } | ||
| 612 | else { | ||
| 613 | ++i; | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | if (droppedJIDs.empty()) { | ||
| 618 | event->ignore(); | ||
| 619 | } | ||
| 620 | else { | ||
| 621 | event->acceptProposedAction(); | ||
| 622 | } | ||
| 601 | } | 623 | } |
| 602 | } | 624 | } |
| 603 | } | 625 | } |
| 604 | } | 626 | } |
| 605 | 627 | ||
| @@ -614,22 +636,26 @@ void QtChatWindow::dropEvent(QDropEvent *event) { | |||
| 614 | message.append(boost::make_shared<ChatTextMessagePart>(messageText)); | 636 | message.append(boost::make_shared<ChatTextMessagePart>(messageText)); |
| 615 | addSystemMessage(message, DefaultDirection); | 637 | addSystemMessage(message, DefaultDirection); |
| 616 | } | 638 | } |
| 617 | } | 639 | } |
| 618 | else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { | 640 | else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { |
| 619 | QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid-list"); | 641 | std::vector<JID> invites = jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list")); |
| 620 | QDataStream dataStream(&dataBytes, QIODevice::ReadOnly); | ||
| 621 | std::vector<JID> invites; | ||
| 622 | while (!dataStream.atEnd()) { | ||
| 623 | QString jidString; | ||
| 624 | dataStream >> jidString; | ||
| 625 | invites.push_back(Q2PSTRING(jidString)); | ||
| 626 | } | ||
| 627 | onInviteToChat(invites); | 642 | onInviteToChat(invites); |
| 628 | } | 643 | } |
| 629 | } | 644 | } |
| 630 | 645 | ||
| 646 | std::vector<JID> QtChatWindow::jidListFromQByteArray(const QByteArray& dataBytes) { | ||
| 647 | QDataStream dataStream(dataBytes); | ||
| 648 | std::vector<JID> invites; | ||
| 649 | while (!dataStream.atEnd()) { | ||
| 650 | QString jidString; | ||
| 651 | dataStream >> jidString; | ||
| 652 | invites.push_back(Q2PSTRING(jidString)); | ||
| 653 | } | ||
| 654 | return invites; | ||
| 655 | } | ||
| 656 | |||
| 631 | void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>& actions) { | 657 | void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>& actions) { |
| 632 | treeWidget_->setAvailableOccupantActions(actions); | 658 | treeWidget_->setAvailableOccupantActions(actions); |
| 633 | } | 659 | } |
| 634 | 660 | ||
| 635 | void QtChatWindow::setSubject(const std::string& subject) { | 661 | void QtChatWindow::setSubject(const std::string& subject) { |
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 | |||
| @@ -183,10 +183,12 @@ namespace Swift { | |||
| 183 | void handleSettingChanged(const std::string& setting); | 183 | void handleSettingChanged(const std::string& setting); |
| 184 | 184 | ||
| 185 | void handleOccupantSelectionChanged(RosterItem* item); | 185 | void handleOccupantSelectionChanged(RosterItem* item); |
| 186 | void handleAppendedToLog(); | 186 | void handleAppendedToLog(); |
| 187 | 187 | ||
| 188 | static std::vector<JID> jidListFromQByteArray(const QByteArray& dataBytes); | ||
| 189 | |||
| 188 | private: | 190 | private: |
| 189 | int unreadCount_; | 191 | int unreadCount_; |
| 190 | bool contactIsTyping_; | 192 | bool contactIsTyping_; |
| 191 | LastLineTracker lastLineTracker_; | 193 | LastLineTracker lastLineTracker_; |
| 192 | std::string id_; | 194 | std::string id_; |
Swift