From fe477c0da80c2e5799a1841ce7fcf4e023ad57bb Mon Sep 17 00:00:00 2001 From: dknn Date: Sat, 24 Mar 2012 16:11:14 +0100 Subject: 'Add contact' from MUC right-click menu This patch allows to add a contact from a MUC, by right clicking a contact in the rooster. The action is only available if the JID of the user is also available License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index b8aa35c..fd37d27 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -121,6 +122,11 @@ void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item actions.push_back(ChatWindow::MakeModerator); actions.push_back(ChatWindow::MakeParticipant); actions.push_back(ChatWindow::MakeVisitor); + + // Add contact is available only if the real JID is also available + if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) { + actions.push_back(ChatWindow::AddContact); + } } chatWindow_->setAvailableOccupantActions(actions); } @@ -138,6 +144,7 @@ void MUCController::handleActionRequestedOnOccupant(ChatWindow::OccupantAction a case ChatWindow::MakeModerator: muc_->changeOccupantRole(mucJID, MUCOccupant::Moderator);break; case ChatWindow::MakeParticipant: muc_->changeOccupantRole(mucJID, MUCOccupant::Participant);break; case ChatWindow::MakeVisitor: muc_->changeOccupantRole(mucJID, MUCOccupant::Visitor);break; + case ChatWindow::AddContact: if (occupant.getRealJID()) events_->send(boost::make_shared(realJID, occupant.getNick()));break; } } diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp index af962e9..47d57d4 100644 --- a/Swift/Controllers/Chat/UserSearchController.cpp +++ b/Swift/Controllers/Chat/UserSearchController.cpp @@ -46,8 +46,9 @@ UserSearchController::~UserSearchController() { void UserSearchController::handleUIEvent(boost::shared_ptr event) { bool handle = false; + boost::shared_ptr request = boost::shared_ptr(); if (type_ == AddContact) { - if (boost::dynamic_pointer_cast(event)) { + if (request = boost::dynamic_pointer_cast(event)) { handle = true; } } else { @@ -65,6 +66,13 @@ void UserSearchController::handleUIEvent(boost::shared_ptr event) { window_->clear(); } window_->show(); + if (request) { + const std::string& name = request->getPredefinedName(); + const JID& jid = request->getPredefinedJID(); + if (!name.empty() && jid.isValid()) { + window_->prepopulateJIDAndName(jid, name); + } + } return; } } diff --git a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h index bfa4a8b..26f48cb 100644 --- a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h @@ -7,9 +7,23 @@ #pragma once #include "Swift/Controllers/UIEvents/UIEvent.h" +#include +#include + namespace Swift { class RequestAddUserDialogUIEvent : public UIEvent { + public: + RequestAddUserDialogUIEvent(const JID& predefinedJID, const std::string& predefinedName) : preJID_(predefinedJID), preName_(predefinedName) {}; + RequestAddUserDialogUIEvent() : preJID_(JID()), preName_(std::string()) {}; + + const JID& getPredefinedJID() const { return preJID_; }; + const std::string& getPredefinedName() const { return preName_; }; + + private: + const JID& preJID_; + const std::string& preName_; + }; } diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index fe7b6bf..acf2381 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -34,7 +34,7 @@ namespace Swift { enum AckState {Pending, Received, Failed}; enum ReceiptState {ReceiptRequested, ReceiptReceived}; enum Tristate {Yes, No, Maybe}; - enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor}; + enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact}; enum FileTransferState {WaitingForAccept, Negotiating, Transferring, Canceled, Finished, FTFailed}; ChatWindow() {} virtual ~ChatWindow() {}; diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindow.h b/Swift/Controllers/UIInterfaces/UserSearchWindow.h index 7ea6849..a3d69d6 100644 --- a/Swift/Controllers/UIInterfaces/UserSearchWindow.h +++ b/Swift/Controllers/UIInterfaces/UserSearchWindow.h @@ -30,6 +30,7 @@ namespace Swift { virtual void setSearchError(bool support) = 0; virtual void setSearchFields(boost::shared_ptr fields) = 0; virtual void setNameSuggestions(const std::vector& suggestions) = 0; + virtual void prepopulateJIDAndName(const JID& jid, const std::string& name) = 0; virtual void show() = 0; boost::signal onFormRequested; diff --git a/Swift/QtUI/Roster/QtOccupantListWidget.cpp b/Swift/QtUI/Roster/QtOccupantListWidget.cpp index 0b3722c..1469300 100644 --- a/Swift/QtUI/Roster/QtOccupantListWidget.cpp +++ b/Swift/QtUI/Roster/QtOccupantListWidget.cpp @@ -57,6 +57,7 @@ void QtOccupantListWidget::contextMenuEvent(QContextMenuEvent* event) { case ChatWindow::MakeModerator: text = tr("Make moderator"); break; case ChatWindow::MakeParticipant: text = tr("Make participant"); break; case ChatWindow::MakeVisitor: text = tr("Remove voice"); break; + case ChatWindow::AddContact: text = tr("Add contact"); break; } QAction* action = contextMenu.addAction(text); actions[action] = availableAction; diff --git a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp index da89a8d..f4189e7 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp +++ b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp @@ -36,6 +36,10 @@ void QtUserSearchDetailsPage::setNameSuggestions(const std::vector& editWidget->setNameSuggestions(nameSuggestions); } +void QtUserSearchDetailsPage::setName(const std::string& name) { + editWidget->setName(name); +} + std::set QtUserSearchDetailsPage::getSelectedGroups() { return editWidget->getSelectedGroups(); } diff --git a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h index 9409493..63fd241 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h +++ b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h @@ -27,6 +27,7 @@ namespace Swift { void setJID(const JID& jid); void setNameSuggestions(const std::vector& nameSuggestions); + void setName(const std::string& name); std::set getSelectedGroups(); std::string getName(); diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp index 949d65c..b8a44e5 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp +++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp @@ -236,6 +236,15 @@ void QtUserSearchWindow::setNameSuggestions(const std::vector& sugg } } +void QtUserSearchWindow::prepopulateJIDAndName(const JID& jid, const std::string& name) { + firstPage_->jid_->setText(P2QSTRING(jid.toBare().toString())); + detailsPage_->setJID(jid); + lastPage_ = 1; + restart(); + next(); + detailsPage_->setName(name); +} + void QtUserSearchWindow::setResults(const std::vector& results) { UserSearchModel *newModel = new UserSearchModel(); newModel->setResults(results); diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h index 9173ba9..32e851a 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h +++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h @@ -40,6 +40,7 @@ namespace Swift { virtual void setSearchError(bool error); virtual void setSearchFields(boost::shared_ptr fields); virtual void setNameSuggestions(const std::vector& suggestions); + virtual void prepopulateJIDAndName(const JID& jid, const std::string& name); protected: virtual int nextId() const; -- cgit v0.10.2-6-g49f6