From 1e61cace31a3395f5470a03c3bcf2b7f32d79d03 Mon Sep 17 00:00:00 2001 From: Mateusz Piekos Date: Sat, 31 Mar 2012 18:34:53 +0200 Subject: Made MUC context options role-aware 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 fd37d27..52cd262 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -86,6 +86,7 @@ MUCController::MUCController ( muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); + muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1)); muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1)); muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3)); @@ -115,14 +116,21 @@ MUCController::~MUCController() { void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item) { std::vector actions; - /* FIXME: all of these should be conditional */ + if (item) { - actions.push_back(ChatWindow::Kick); - actions.push_back(ChatWindow::Ban); - actions.push_back(ChatWindow::MakeModerator); - actions.push_back(ChatWindow::MakeParticipant); - actions.push_back(ChatWindow::MakeVisitor); + MUCOccupant::Affiliation affiliation = muc_->getOccupant(getNick()).getAffiliation(); + MUCOccupant::Role role = muc_->getOccupant(getNick()).getRole(); + if (role == MUCOccupant::Moderator) + { + if (affiliation == MUCOccupant::Admin || affiliation == MUCOccupant::Owner) { + actions.push_back(ChatWindow::Ban); + } + actions.push_back(ChatWindow::Kick); + 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); @@ -259,6 +267,8 @@ void MUCController::handleJoinComplete(const std::string& nick) { clearPresenceQueue(); shouldJoinOnReconnect_ = true; setEnabled(true); + MUCOccupant occupant = muc_->getOccupant(nick); + setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); onUserJoined(); } @@ -319,6 +329,29 @@ void MUCController::addPresenceMessage(const std::string& message) { chatWindow_->addPresenceMessage(message); } + +void MUCController::setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role) +{ + std::vector actions; + + if (role <= MUCOccupant::Participant) { + actions.push_back(ChatWindow::ChangeSubject); + } + if (affiliation == MUCOccupant::Owner) { + actions.push_back(ChatWindow::Configure); + } + if (affiliation <= MUCOccupant::Admin) { + actions.push_back(ChatWindow::Affiliations); + } + if (affiliation == MUCOccupant::Owner) { + actions.push_back(ChatWindow::Destroy); + } + if (role <= MUCOccupant::Visitor) { + actions.push_back(ChatWindow::Invite); + } + chatWindow_->setAvailableRoomActions(actions); +} + void MUCController::clearPresenceQueue() { lastWasPresence_ = false; joinParts_.clear(); @@ -410,6 +443,16 @@ void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUC roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid).string()); roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole())); chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole()))); + if (nick == nick_) { + setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); + } +} + +void MUCController::handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Affiliation& oldAffiliation) +{ + if (nick == nick_) { + setAvailableRoomActions(affiliation, muc_->getOccupant(nick_).getRole()); + } } std::string MUCController::roleToGroupName(MUCOccupant::Role role) { diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 16dcb99..6906f81 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -63,6 +63,7 @@ namespace Swift { void postHandleIncomingMessage(boost::shared_ptr); private: + void setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role); void clearPresenceQueue(); void addPresenceMessage(const std::string& message); void handleWindowOccupantSelectionChanged(ContactRosterItem* item); @@ -73,6 +74,7 @@ namespace Swift { void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason); void handleOccupantPresenceChange(boost::shared_ptr presence); void handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant,const MUCOccupant::Role& oldRole); + void handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation,const MUCOccupant::Affiliation& oldAffiliation); void handleJoinComplete(const std::string& nick); void handleJoinFailed(boost::shared_ptr error); void handleJoinTimeoutTick(); diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index acf2381..e7246c6 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -35,6 +35,7 @@ namespace Swift { enum ReceiptState {ReceiptRequested, ReceiptReceived}; enum Tristate {Yes, No, Maybe}; enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact}; + enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite}; enum FileTransferState {WaitingForAccept, Negotiating, Transferring, Canceled, Finished, FTFailed}; ChatWindow() {} virtual ~ChatWindow() {}; @@ -81,7 +82,7 @@ namespace Swift { virtual void flash() = 0; virtual void setSubject(const std::string& subject) = 0; virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector&) = 0; - + virtual void setAvailableRoomActions(const std::vector &actions) = 0; /** * Set an alert on the window. * @param alertText Description of alert (required). diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index ce012c6..dab1e90 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -52,6 +52,7 @@ namespace Swift { virtual void showRoomConfigurationForm(Form::ref) {} virtual void addMUCInvitation(const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool = true) {}; virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector&) {} + virtual void setAvailableRoomActions(const std::vector &) {}; std::string name_; std::string lastMessageBody_; diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index dc89c21..c6519ba 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -732,11 +732,24 @@ void QtChatWindow::setSubject(const std::string& subject) { void QtChatWindow::handleActionButtonClicked() { QMenu contextMenu; - QAction* changeSubject = contextMenu.addAction(tr("Change subject")); - QAction* configure = contextMenu.addAction(tr("Configure room")); - QAction* affiliations = contextMenu.addAction(tr("Edit affiliations")); - QAction* destroy = contextMenu.addAction(tr("Destroy room")); - QAction* invite = contextMenu.addAction(tr("Invite person to this room")); + QAction* changeSubject = NULL; + QAction* configure = NULL; + QAction* affiliations = NULL; + QAction* destroy = NULL; + QAction* invite = NULL; + + foreach(ChatWindow::RoomAction availableAction, availableRoomActions_) + { + switch(availableAction) + { + case ChatWindow::ChangeSubject: changeSubject = contextMenu.addAction(tr("Change subject")); break; + case ChatWindow::Configure: configure = contextMenu.addAction(tr("Configure room")); break; + case ChatWindow::Affiliations: affiliations = contextMenu.addAction(tr("Edit affiliations")); break; + case ChatWindow::Destroy: destroy = contextMenu.addAction(tr("Destroy room")); break; + case ChatWindow::Invite: invite = contextMenu.addAction(tr("Invite person to this room")); break; + } + } + QAction* result = contextMenu.exec(QCursor::pos()); if (result == changeSubject) { bool ok; @@ -785,6 +798,11 @@ void QtChatWindow::setAffiliations(MUCOccupant::Affiliation affiliation, const s affiliationEditor_->setAffiliations(affiliation, jids); } +void QtChatWindow::setAvailableRoomActions(const std::vector &actions) +{ + availableRoomActions_ = actions; +} + void QtChatWindow::showRoomConfigurationForm(Form::ref form) { if (mucConfigurationWindow_) { delete mucConfigurationWindow_.data(); diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 9203068..189a12a 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -79,6 +79,7 @@ namespace Swift { void showRoomConfigurationForm(Form::ref); void addMUCInvitation(const JID& jid, const std::string& reason, const std::string& password, bool direct = true); void setAffiliations(MUCOccupant::Affiliation, const std::vector&); + void setAvailableRoomActions(const std::vector &actions); public slots: void handleChangeSplitterState(QByteArray state); @@ -163,5 +164,6 @@ namespace Swift { QPointer affiliationEditor_; int idCounter_; SettingsProvider* settings_; + std::vector availableRoomActions_; }; } -- cgit v0.10.2-6-g49f6