summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llavataractions.cpp12
-rw-r--r--indra/newview/llavataractions.h5
-rw-r--r--indra/newview/llchathistory.cpp264
-rw-r--r--indra/newview/llfloaterimcontainer.cpp22
-rw-r--r--indra/newview/llfloaterimcontainer.h1
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_icon.xml44
6 files changed, 306 insertions, 42 deletions
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 219d9da01f..8fe684ad79 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -1005,7 +1005,7 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
}
// static
-void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
+void LLAvatarActions::toggleMute(const LLUUID& id, U32 flags)
{
LLAvatarName av_name;
LLAvatarNameCache::get(id, &av_name);
@@ -1016,15 +1016,21 @@ void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
if (!is_muted)
{
- mute_list->add(mute, LLMute::flagVoiceChat);
+ mute_list->add(mute, flags);
}
else
{
- mute_list->remove(mute, LLMute::flagVoiceChat);
+ mute_list->remove(mute, flags);
}
}
// static
+void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
+{
+ toggleMute(id, LLMute::flagVoiceChat);
+}
+
+// static
bool LLAvatarActions::canOfferTeleport(const LLUUID& id)
{
// First use LLAvatarTracker::isBuddy()
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 256d44d820..b56d5b0fb9 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -131,6 +131,11 @@ public:
static void toggleBlock(const LLUUID& id);
/**
+ * Mute/unmute avatar.
+ */
+ static void toggleMute(const LLUUID& id, U32 flags);
+
+ /**
* Block/unblock the avatar voice.
*/
static void toggleMuteVoice(const LLUUID& id);
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 9798ef3529..5748eeec47 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -38,10 +38,14 @@
#include "llpanel.h"
#include "lluictrlfactory.h"
#include "llscrollcontainer.h"
-#include "llavatariconctrl.h"
-#include "llcallingcard.h" //for LLAvatarTracker
+#include "llagent.h"
#include "llagentdata.h"
#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llcallingcard.h" //for LLAvatarTracker
+#include "llgroupactions.h"
+#include "llgroupmgr.h"
+#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
@@ -49,7 +53,6 @@
#include "llstylemap.h"
#include "llslurl.h"
#include "lllayoutstack.h"
-#include "llagent.h"
#include "llnotificationsutil.h"
#include "lltoastnotifypanel.h"
#include "lltooltip.h"
@@ -61,7 +64,6 @@
#include "llurlaction.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
-#include "llmutelist.h"
static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
@@ -187,6 +189,161 @@ public:
return false;
}
+ void banGroupMember(const LLUUID& participant_uuid)
+ {
+ LLUUID group_uuid = mSessionID;
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid);
+ if (!gdatap)
+ {
+ // Not a group
+ return;
+ }
+
+ gdatap->banMemberById(participant_uuid);
+ }
+
+ bool canBanInGroup()
+ {
+ LLUUID group_uuid = mSessionID;
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid);
+ if (!gdatap)
+ {
+ // Not a group
+ return false;
+ }
+
+ if (gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER)
+ && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ bool canBanGroupMember(const LLUUID& participant_uuid)
+ {
+ LLUUID group_uuid = mSessionID;
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid);
+ if (!gdatap)
+ {
+ // Not a group
+ return false;
+ }
+
+ if (gdatap->mPendingBanRequest)
+ {
+ return false;
+ }
+
+ if (gAgentID == getAvatarId())
+ {
+ //Don't ban self
+ return false;
+ }
+
+ if (gdatap->isRoleMemberDataComplete())
+ {
+ if (gdatap->mMembers.size())
+ {
+ LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(participant_uuid);
+ if (mi != gdatap->mMembers.end())
+ {
+ LLGroupMemberData* member_data = (*mi).second;
+ // Is the member an owner?
+ if (member_data && member_data->isInRole(gdatap->mOwnerRole))
+ {
+ return false;
+ }
+
+ if (gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER)
+ && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ LLSpeaker * speakerp = speaker_mgr->findSpeaker(participant_uuid).get();
+
+ if (speakerp
+ && gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER)
+ && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool isGroupModerator()
+ {
+ LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (!speaker_mgr)
+ {
+ LL_WARNS() << "Speaker manager is missing" << LL_ENDL;
+ return false;
+ }
+
+ // Is session a group call/chat?
+ if(gAgent.isInGroup(mSessionID))
+ {
+ LLSpeaker * speakerp = speaker_mgr->findSpeaker(gAgentID).get();
+
+ // Is agent a moderator?
+ return speakerp && speakerp->mIsModerator;
+ }
+
+ return false;
+ }
+
+ bool canModerate(const std::string& userdata)
+ {
+ // only group moderators can perform actions related to this "enable callback"
+ if (!isGroupModerator() || gAgentID == getAvatarId())
+ {
+ return false;
+ }
+
+ LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (!speaker_mgr)
+ {
+ return false;
+ }
+
+ LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get();
+ if (!speakerp)
+ {
+ return false;
+ }
+
+ bool voice_channel = speakerp->isInVoiceChannel();
+
+ if ("can_moderate_voice" == userdata)
+ {
+ return voice_channel;
+ }
+ else if ("can_mute" == userdata)
+ {
+ return voice_channel && (speakerp->mStatus != LLSpeaker::STATUS_MUTED);
+ }
+ else if ("can_unmute" == userdata)
+ {
+ return speakerp->mStatus == LLSpeaker::STATUS_MUTED;
+ }
+ else if ("can_allow_text_chat" == userdata)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
void onAvatarIconContextMenuItemClicked(const LLSD& userdata)
{
std::string level = userdata.asString();
@@ -245,11 +402,36 @@ public:
}
else if(level == "block_unblock")
{
- mute(getAvatarId(), LLMute::flagVoiceChat);
+ LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
}
else if(level == "mute_unmute")
{
- mute(getAvatarId(), LLMute::flagTextChat);
+ LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagTextChat);
+ }
+ else if(level == "toggle_allow_text_chat")
+ {
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ speaker_mgr->toggleAllowTextChat(getAvatarId());
+ }
+ else if(level == "group_mute")
+ {
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ speaker_mgr->moderateVoiceParticipant(getAvatarId(), false);
+ }
+ }
+ else if(level == "group_unmute")
+ {
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ speaker_mgr->moderateVoiceParticipant(getAvatarId(), true);
+ }
+ }
+ else if(level == "ban_member")
+ {
+ banGroupMember(getAvatarId());
}
}
@@ -265,24 +447,69 @@ public:
{
return LLMuteList::getInstance()->isMuted(getAvatarId(), LLMute::flagTextChat);
}
+ else if (level == "is_allowed_text_chat")
+ {
+ if (gAgent.isInGroup(mSessionID))
+ {
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ const LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId());
+
+ if (NULL != speakerp)
+ {
+ return !speakerp->mModeratorMutedText;
+ }
+ }
+ return false;
+ }
return false;
}
- void mute(const LLUUID& participant_id, U32 flags)
+ bool onAvatarIconContextMenuItemEnabled(const LLSD& userdata)
{
- BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
- LLAvatarName av_name;
- LLAvatarNameCache::get(participant_id, &av_name);
- LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT);
+ std::string level = userdata.asString();
- if (!is_muted)
+ if (level == "can_allow_text_chat" || level == "can_mute" || level == "can_unmute")
{
- LLMuteList::getInstance()->add(mute, flags);
+ return canModerate(userdata);
}
- else
+ else if (level == "can_ban_member")
{
- LLMuteList::getInstance()->remove(mute, flags);
+ return canBanGroupMember(getAvatarId());
}
+ return false;
+ }
+
+ bool onAvatarIconContextMenuItemVisible(const LLSD& userdata)
+ {
+ std::string level = userdata.asString();
+
+ if (level == "show_mute")
+ {
+ LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get();
+ if (speakerp)
+ {
+ return speakerp->isInVoiceChannel() && speakerp->mStatus != LLSpeaker::STATUS_MUTED;
+ }
+ }
+ return false;
+ }
+ else if (level == "show_unmute")
+ {
+ LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get();
+ if (speakerp)
+ {
+ return speakerp->mStatus == LLSpeaker::STATUS_MUTED;
+ }
+ }
+ return false;
+ }
+ return false;
}
BOOL postBuild()
@@ -292,6 +519,8 @@ public:
registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
+ registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2));
+ registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2));
registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
@@ -567,9 +796,14 @@ protected:
if(menu)
{
bool is_friend = LLAvatarActions::isFriend(mAvatarID);
+ bool is_group_session = gAgent.isInGroup(mSessionID);
menu->setItemEnabled("Add Friend", !is_friend);
menu->setItemEnabled("Remove Friend", is_friend);
+ menu->setItemVisible("Moderator Options Separator", is_group_session && isGroupModerator());
+ menu->setItemVisible("Moderator Options", is_group_session && isGroupModerator());
+ menu->setItemVisible("Group Ban Separator", is_group_session && canBanInGroup());
+ menu->setItemVisible("BanMember", is_group_session && canBanInGroup());
if(gAgentID == mAvatarID)
{
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3522932d03..333765f99f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1150,11 +1150,11 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
}
else if ("block_unblock" == command)
{
- toggleMute(userID, LLMute::flagVoiceChat);
+ LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat);
}
else if ("mute_unmute" == command)
{
- toggleMute(userID, LLMute::flagTextChat);
+ LLAvatarActions::toggleMute(userID, LLMute::flagTextChat);
}
else if ("selected" == command || "mute_all" == command || "unmute_all" == command)
{
@@ -2096,24 +2096,6 @@ void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
}
}
-void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags)
-{
- BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
-
- LLAvatarName av_name;
- LLAvatarNameCache::get(participant_id, &av_name);
- LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT);
-
- if (!is_muted)
- {
- LLMuteList::getInstance()->add(mute, flags);
- }
- else
- {
- LLMuteList::getInstance()->remove(mute, flags);
- }
-}
-
void LLFloaterIMContainer::openNearbyChat()
{
// If there's only one conversation in the container and that conversation is the nearby chat
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 60cef83d9a..90fc0c2bdd 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -176,7 +176,6 @@ private:
void moderateVoiceAllParticipants(bool unmute);
void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
void toggleAllowTextChat(const LLUUID& participant_uuid);
- void toggleMute(const LLUUID& participant_id, U32 flags);
void banSelectedMember(const LLUUID& participant_uuid);
void openNearbyChat();
bool isParticipantListExpanded();
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
index 410caa7290..05ab4d35a0 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu
+<toggleable_menu
height="101"
layout="topleft"
left="100"
@@ -109,5 +109,43 @@
name="Mute Text">
<on_click function="AvatarIcon.Action" parameter="mute_unmute" />
<on_check function="AvatarIcon.Check" parameter="is_muted" />
- </menu_item_check>
-</menu>
+ </menu_item_check>
+ <menu_item_separator layout="topleft" name="Moderator Options Separator"/>
+ <context_menu
+ label="Moderator Options"
+ layout="topleft"
+ name="Moderator Options">
+ <menu_item_check
+ label="Allow text chat"
+ layout="topleft"
+ name="AllowTextChat">
+ <on_check function="AvatarIcon.Check" parameter="is_allowed_text_chat" />
+ <on_click function="AvatarIcon.Action" parameter="toggle_allow_text_chat" />
+ <on_enable function="AvatarIcon.Enable" parameter="can_allow_text_chat" />
+ </menu_item_check>
+ <menu_item_call
+ label="Mute this participant"
+ layout="topleft"
+ name="ModerateVoiceMuteSelected">
+ <on_click function="AvatarIcon.Action" parameter="group_mute" />
+ <on_enable function="AvatarIcon.Enable" parameter="can_mute" />
+ <on_visible function="AvatarIcon.Visible" parameter="show_mute" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unmute this participant"
+ layout="topleft"
+ name="ModerateVoiceUnMuteSelected">
+ <on_click function="AvatarIcon.Action" parameter="group_unmute" />
+ <on_enable function="AvatarIcon.Enable" parameter="can_unmute" />
+ <on_visible function="AvatarIcon.Visible" parameter="show_unmute" />
+ </menu_item_call>
+ </context_menu>
+ <menu_item_separator layout="topleft" name="Group Ban Separator"/>
+ <menu_item_call
+ label="Ban member"
+ layout="topleft"
+ name="BanMember">
+ <on_click function="AvatarIcon.Action" parameter="ban_member" />
+ <on_enable function="AvatarIcon.Enable" parameter="can_ban_member" />
+ </menu_item_call>
+</toggleable_menu>