summaryrefslogtreecommitdiff
path: root/indra/newview/llparticipantlist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llparticipantlist.cpp')
-rw-r--r--indra/newview/llparticipantlist.cpp270
1 files changed, 179 insertions, 91 deletions
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 48a7a32a3b..93e5b8fa15 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -42,11 +42,13 @@
#include "llavatarlist.h"
#include "llspeakers.h"
#include "llviewermenu.h"
+#include "llvoiceclient.h"
//LLParticipantList retrieves add, clear and remove events and updates view accordingly
#if LL_MSVC
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
+
LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu/* = true*/):
mSpeakerMgr(data_source),
mAvatarList(avatar_list),
@@ -57,6 +59,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
+ mSpeakerMuteListener = new SpeakerMuteListener(*this);
mSpeakerMgr->addListener(mSpeakerAddListener, "add");
mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
@@ -87,6 +90,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av
for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++)
{
const LLPointer<LLSpeaker>& speakerp = *it;
+
addAvatarIDExceptAgent(group_members, speakerp->mID);
if ( speakerp->mIsModerator )
{
@@ -103,6 +107,14 @@ LLParticipantList::~LLParticipantList()
mAvatarListRefreshConnection.disconnect();
mAvatarListReturnConnection.disconnect();
+ // It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged()
+ // See ticket EXT-3427
+ // hide menu before deleting it to stop enable and check handlers from triggering.
+ if(mParticipantListMenu)
+ {
+ mParticipantListMenu->hide();
+ }
+
delete mParticipantListMenu;
mParticipantListMenu = NULL;
}
@@ -184,6 +196,27 @@ void LLParticipantList::setSortOrder(EParticipantSortOrder order)
}
}
+void LLParticipantList::refreshVoiceState()
+{
+ LLSpeakerMgr::speaker_list_t speakers;
+ mSpeakerMgr->getSpeakerList(&speakers, TRUE);
+
+ for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin();
+ iter != speakers.end(); ++iter)
+ {
+ LLSpeaker* speakerp = (*iter).get();
+ const LLUUID& speaker_id = speakerp->mID;
+ LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (mAvatarList->getItemByValue(speaker_id));
+ if ( item )
+ {
+ // if voice is disabled for this speaker show non voice speakers as disabled
+ bool is_in_voice = speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE
+ && speakerp->mStatus != LLSpeaker::STATUS_MUTED;
+ item->setOnline(!is_in_voice);
+ }
+ }
+}
+
bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs();
@@ -248,6 +281,24 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> e
return true;
}
+bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ LLPointer<LLSpeaker> speakerp = (LLSpeaker*)event->getSource();
+ if (speakerp.isNull()) return false;
+
+ // update UI on confirmation of moderator mutes
+ if (event->getValue().asString() == "voice")
+ {
+ LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(mAvatarList->getItemByValue(speakerp->mID));
+ if (item)
+ {
+ LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator");
+ indicator->setIsMuted(speakerp->mModeratorMutedVoice);
+ }
+ }
+ return true;
+}
+
void LLParticipantList::sort()
{
if ( !mAvatarList )
@@ -264,13 +315,21 @@ void LLParticipantList::sort()
}
}
-// static
void LLParticipantList::addAvatarIDExceptAgent(std::vector<LLUUID>& existing_list, const LLUUID& avatar_id)
{
- if (gAgent.getID() != avatar_id)
- {
- existing_list.push_back(avatar_id);
- }
+ if (gAgent.getID() == avatar_id) return;
+
+ existing_list.push_back(avatar_id);
+ adjustParticipant(avatar_id);
+}
+
+void LLParticipantList::adjustParticipant(const LLUUID& speaker_id)
+{
+ LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(speaker_id);
+ if (speakerp.isNull()) return;
+
+ // add listener to process moderation changes
+ speakerp->addListener(mSpeakerMuteListener);
}
//
@@ -315,6 +374,11 @@ bool LLParticipantList::SpeakerModeratorUpdateListener::handleEvent(LLPointer<LL
return mParent.onModeratorUpdateEvent(event, userdata);
}
+bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ return mParent.onSpeakerMuteEvent(event, userdata);
+}
+
LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
{
// set up the callbacks for all of the avatar menu items
@@ -324,14 +388,27 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleAllowTextChat, this, _2));
registrar.add("ParticipantList.ToggleMuteText", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteText, this, _2));
+ registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, mUUIDs.front()));
+ registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mUUIDs.front()));
+ registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs.front()));
+ registrar.add("Avatar.BlockUnblock", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteVoice, this, _2));
+ registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, mUUIDs.front()));
+ registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs.front()));
+ registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, mUUIDs.front()));
+
registrar.add("ParticipantList.ModerateVoice", boost::bind(&LLParticipantList::LLParticipantListMenu::moderateVoice, this, _2));
enable_registrar.add("ParticipantList.EnableItem", boost::bind(&LLParticipantList::LLParticipantListMenu::enableContextMenuItem, this, _2));
enable_registrar.add("ParticipantList.CheckItem", boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem, this, _2));
// create the context menu from the XUI
- return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ main_menu->setItemVisible("Moderator Options", isGroupModerator());
+ main_menu->arrangeAndClear();
+
+ return main_menu;
}
void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const std::vector<LLUUID>& uuids, S32 x, S32 y)
@@ -341,7 +418,7 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const
if (uuids.size() == 0) return;
const LLUUID speaker_id = mUUIDs.front();
- BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, LLMute::flagVoiceChat);
+ BOOL is_muted = isMuted(speaker_id);
if (is_muted)
{
@@ -353,64 +430,17 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteSelected", false);
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteOthers", false);
}
-
}
void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata)
{
- const LLUUID speaker_id = mUUIDs.front();
- std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
- LLSD data;
- data["method"] = "mute update";
- data["session-id"] = mParent.mSpeakerMgr->getSessionID();
- data["params"] = LLSD::emptyMap();
- data["params"]["agent_id"] = speaker_id;
- data["params"]["mute_info"] = LLSD::emptyMap();
- //current value represents ability to type, so invert
- data["params"]["mute_info"]["text"] = !mParent.mSpeakerMgr->findSpeaker(speaker_id)->mModeratorMutedText;
-
- class MuteTextResponder : public LLHTTPClient::Responder
+ LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
+ if (mgr)
{
- public:
- MuteTextResponder(const LLUUID& session_id)
- {
- mSessionID = session_id;
- }
-
- virtual void error(U32 status, const std::string& reason)
- {
- llwarns << status << ": " << reason << llendl;
-
- if ( gIMMgr )
- {
- //403 == you're not a mod
- //should be disabled if you're not a moderator
- if ( 403 == status )
- {
- gIMMgr->showSessionEventError(
- "mute",
- "not_a_moderator",
- mSessionID);
- }
- else
- {
- gIMMgr->showSessionEventError(
- "mute",
- "generic",
- mSessionID);
- }
- }
- }
-
- private:
- LLUUID mSessionID;
- };
-
- LLHTTPClient::post(
- url,
- data,
- new MuteTextResponder(mParent.mSpeakerMgr->getSessionID()));
+ const LLUUID speaker_id = mUUIDs.front();
+ mgr->toggleAllowTextChat(speaker_id);
+ }
}
void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata, U32 flags)
@@ -450,36 +480,59 @@ void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userd
toggleMute(userdata, LLMute::flagVoiceChat);
}
-void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdata)
+bool LLParticipantList::LLParticipantListMenu::isGroupModerator()
+{
+ // Agent is in Group Call
+ if(gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID()))
+ {
+ // Agent is Moderator
+ return mParent.mSpeakerMgr->findSpeaker(gAgentID)->mIsModerator;
+ }
+ return false;
+}
+
+bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id)
{
+ LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id);
+ if (!selected_speakerp) return true;
+ return selected_speakerp->mStatus == LLSpeaker::STATUS_MUTED;
}
-void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLSD& userdata)
+
+void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdata)
{
- LLSpeakerMgr::speaker_list_t speakers;
- mParent.mSpeakerMgr->getSpeakerList(&speakers, true);
+ if (!gAgent.getRegion()) return;
- const LLUUID& excluded_avatar_id = mUUIDs.front();
- bool should_mute = userdata.asString() == "mute";
- for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin();
- iter != speakers.end(); ++iter)
- {
- LLSpeaker* speakerp = (*iter).get();
- LLUUID speaker_id = speakerp->mID;
- if (excluded_avatar_id == speaker_id) continue;
+ bool moderate_selected = userdata.asString() == "selected";
+ const LLUUID& selected_avatar_id = mUUIDs.front();
+ bool is_muted = isMuted(selected_avatar_id);
- LLMute mute(speaker_id, speakerp->mDisplayName, speakerp->mType == LLSpeaker::SPEAKER_AGENT ? LLMute::AGENT : LLMute::OBJECT);
+ if (moderate_selected)
+ {
+ moderateVoiceParticipant(selected_avatar_id, is_muted);
+ }
+ else
+ {
+ moderateVoiceOtherParticipants(selected_avatar_id, is_muted);
+ }
+}
- if (should_mute)
- {
- LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat);
- }
- else
- {
- LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat);
- }
+void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
+{
+ LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
+ if (mgr)
+ {
+ mgr->moderateVoiceParticipant(avatar_id, unmute);
}
+}
+void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute)
+{
+ LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
+ if (mgr)
+ {
+ mgr->moderateVoiceOtherParticipants(excluded_avatar_id, unmute);
+ }
}
bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata)
@@ -492,9 +545,35 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
else
if (item == "can_allow_text_chat" || "can_moderate_voice" == item)
{
- LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mParent.mSpeakerMgr->getSessionID());
- return im_session->mType == IM_SESSION_GROUP_START && mParent.mSpeakerMgr->findSpeaker(gAgentID)->mIsModerator;
+ return isGroupModerator();
+ }
+ else if (item == std::string("can_add"))
+ {
+ // We can add friends if:
+ // - there are selected people
+ // - and there are no friends among selection yet.
+
+ bool result = (mUUIDs.size() > 0);
+
+ std::vector<LLUUID>::const_iterator
+ id = mUUIDs.begin(),
+ uuids_end = mUUIDs.end();
+
+ for (;id != uuids_end; ++id)
+ {
+ if ( LLAvatarActions::isFriend(*id) )
+ {
+ result = false;
+ break;
+ }
+ }
+ return result;
}
+ else if (item == "can_call")
+ {
+ return LLVoiceClient::voiceEnabled();
+ }
+
return true;
}
@@ -502,17 +581,26 @@ bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD&
{
std::string item = userdata.asString();
const LLUUID& id = mUUIDs.front();
+
if (item == "is_muted")
- return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat);
- else
- if (item == "is_allowed_text_chat")
- {
- LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id);
+ {
+ return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat);
+ }
+ else if (item == "is_allowed_text_chat")
+ {
+ LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id);
- if (selected_speakerp.notNull())
- {
- return !selected_speakerp->mModeratorMutedText;
- }
+ if (selected_speakerp.notNull())
+ {
+ return !selected_speakerp->mModeratorMutedText;
}
+ }
+ else if(item == "is_blocked")
+ {
+ return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
+ }
+
return false;
}
+
+//EOF