Merge. Refresh from viewer-release after 3.7.13 release.
commit
9a8b1552f0
1
.hgtags
1
.hgtags
|
|
@ -485,3 +485,4 @@ a9f2d0cb11f73b06858e6083bb50083becc3f9cd 3.7.9-release
|
|||
91dae9494b4d147541c7a01902334ba19a7ec05e 3.7.10-release
|
||||
64799eb298834073a3e9992cd8d27c3cb9d30b10 3.7.11-release
|
||||
3b44ea8988cb902f0dda8429e8d5e4569e304532 3.7.12-release
|
||||
d86a7e1bc96d27b683f951d3701d5b7042158c68 3.7.13-release
|
||||
|
|
|
|||
|
|
@ -477,7 +477,8 @@ void LLToolTipMgr::show(const std::string& msg)
|
|||
void LLToolTipMgr::show(const LLToolTip::Params& params)
|
||||
{
|
||||
if (!params.styled_message.isProvided()
|
||||
&& (!params.message.isProvided() || params.message().empty())) return;
|
||||
&& (!params.message.isProvided() || params.message().empty())
|
||||
&& !params.image.isProvided()) return;
|
||||
|
||||
// fill in default tooltip params from tool_tip.xml
|
||||
LLToolTip::Params params_with_defaults(params);
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloatergesture.cpp
|
||||
llfloatergodtools.cpp
|
||||
llfloatergotoline.cpp
|
||||
llfloatergroupbulkban.cpp
|
||||
llfloatergroupinvite.cpp
|
||||
llfloatergroups.cpp
|
||||
llfloaterhandler.cpp
|
||||
|
|
@ -412,6 +413,8 @@ set(viewer_SOURCE_FILES
|
|||
llpanelface.cpp
|
||||
llpanelgenerictip.cpp
|
||||
llpanelgroup.cpp
|
||||
llpanelgroupbulk.cpp
|
||||
llpanelgroupbulkban.cpp
|
||||
llpanelgroupgeneral.cpp
|
||||
llpanelgroupinvite.cpp
|
||||
llpanelgrouplandmoney.cpp
|
||||
|
|
@ -839,6 +842,7 @@ set(viewer_HEADER_FILES
|
|||
llfloatergesture.h
|
||||
llfloatergodtools.h
|
||||
llfloatergotoline.h
|
||||
llfloatergroupbulkban.h
|
||||
llfloatergroupinvite.h
|
||||
llfloatergroups.h
|
||||
llfloaterhandler.h
|
||||
|
|
@ -1006,6 +1010,9 @@ set(viewer_HEADER_FILES
|
|||
llpanelface.h
|
||||
llpanelgenerictip.h
|
||||
llpanelgroup.h
|
||||
llpanelgroupbulk.h
|
||||
llpanelgroupbulkimpl.h
|
||||
llpanelgroupbulkban.h
|
||||
llpanelgroupgeneral.h
|
||||
llpanelgroupinvite.h
|
||||
llpanelgrouplandmoney.h
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.7.13
|
||||
3.7.14
|
||||
|
|
|
|||
|
|
@ -6118,16 +6118,16 @@
|
|||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MemoryLogFrequency</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Seconds between display of Memory in log (0 for never)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>600.0</real>
|
||||
</map>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Seconds between display of Memory in log (0 for never)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>30.0</real>
|
||||
</map>
|
||||
<key>MemoryPrivatePoolEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
|
|||
mConvType(CONV_UNKNOWN),
|
||||
mLastActiveTime(0.0),
|
||||
mDisplayModeratorOptions(false),
|
||||
mDisplayGroupBanOptions(false),
|
||||
mAvatarNameCacheConnection()
|
||||
{
|
||||
}
|
||||
|
|
@ -63,6 +64,7 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte
|
|||
mConvType(CONV_UNKNOWN),
|
||||
mLastActiveTime(0.0),
|
||||
mDisplayModeratorOptions(false),
|
||||
mDisplayGroupBanOptions(false),
|
||||
mAvatarNameCacheConnection()
|
||||
{
|
||||
}
|
||||
|
|
@ -75,6 +77,7 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
|
|||
mConvType(CONV_UNKNOWN),
|
||||
mLastActiveTime(0.0),
|
||||
mDisplayModeratorOptions(false),
|
||||
mDisplayGroupBanOptions(false),
|
||||
mAvatarNameCacheConnection()
|
||||
{
|
||||
}
|
||||
|
|
@ -159,6 +162,12 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
|
|||
items.push_back(std::string("ModerateVoiceMute"));
|
||||
items.push_back(std::string("ModerateVoiceUnmute"));
|
||||
}
|
||||
|
||||
if ((getType() != CONV_SESSION_1_ON_1) && mDisplayGroupBanOptions)
|
||||
{
|
||||
items.push_back(std::string("Group Ban Separator"));
|
||||
items.push_back(std::string("BanMember"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ protected:
|
|||
bool mNeedsRefresh; // Flag signaling to the view that something changed for this item
|
||||
F64 mLastActiveTime;
|
||||
bool mDisplayModeratorOptions;
|
||||
bool mDisplayGroupBanOptions;
|
||||
boost::signals2::connection mAvatarNameCacheConnection;
|
||||
};
|
||||
|
||||
|
|
@ -206,6 +207,7 @@ public:
|
|||
void dumpDebugData();
|
||||
void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
|
||||
void setDisplayModeratorRole(bool displayRole);
|
||||
void setGroupBanVisible(bool visible) { mDisplayGroupBanOptions = visible; }
|
||||
|
||||
private:
|
||||
void onAvatarNameCache(const LLAvatarName& av_name); // callback used by fetchAvatarName
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* @file llfloatergroupbulkban.cpp
|
||||
* @brief Floater to ban Residents from a group.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatergroupbulkban.h"
|
||||
#include "llpanelgroupbulkban.h"
|
||||
#include "lltrans.h"
|
||||
#include "lldraghandle.h"
|
||||
|
||||
|
||||
class LLFloaterGroupBulkBan::impl
|
||||
{
|
||||
public:
|
||||
impl(const LLUUID& group_id) : mGroupID(group_id), mBulkBanPanelp(NULL) {}
|
||||
~impl() {}
|
||||
|
||||
static void closeFloater(void* data);
|
||||
|
||||
public:
|
||||
LLUUID mGroupID;
|
||||
LLPanelGroupBulkBan* mBulkBanPanelp;
|
||||
|
||||
static std::map<LLUUID, LLFloaterGroupBulkBan*> sInstances;
|
||||
};
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
std::map<LLUUID, LLFloaterGroupBulkBan*> LLFloaterGroupBulkBan::impl::sInstances;
|
||||
|
||||
void LLFloaterGroupBulkBan::impl::closeFloater(void* data)
|
||||
{
|
||||
LLFloaterGroupBulkBan* floaterp = (LLFloaterGroupBulkBan*)data;
|
||||
if(floaterp)
|
||||
floaterp->closeFloater();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
LLFloaterGroupBulkBan::LLFloaterGroupBulkBan(const LLUUID& group_id/*=LLUUID::null*/)
|
||||
: LLFloater(group_id)
|
||||
{
|
||||
S32 floater_header_size = getHeaderHeight();
|
||||
LLRect contents;
|
||||
|
||||
mImpl = new impl(group_id);
|
||||
mImpl->mBulkBanPanelp = new LLPanelGroupBulkBan(group_id);
|
||||
|
||||
contents = mImpl->mBulkBanPanelp->getRect();
|
||||
contents.mTop -= floater_header_size;
|
||||
|
||||
setTitle(mImpl->mBulkBanPanelp->getString("GroupBulkBan"));
|
||||
mImpl->mBulkBanPanelp->setCloseCallback(impl::closeFloater, this);
|
||||
mImpl->mBulkBanPanelp->setRect(contents);
|
||||
|
||||
addChild(mImpl->mBulkBanPanelp);
|
||||
}
|
||||
|
||||
LLFloaterGroupBulkBan::~LLFloaterGroupBulkBan()
|
||||
{
|
||||
if(mImpl->mGroupID.notNull())
|
||||
{
|
||||
impl::sInstances.erase(mImpl->mGroupID);
|
||||
}
|
||||
|
||||
delete mImpl->mBulkBanPanelp;
|
||||
delete mImpl;
|
||||
}
|
||||
|
||||
void LLFloaterGroupBulkBan::showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids)
|
||||
{
|
||||
const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
|
||||
S32 floater_header_size = floater_params.header_height;
|
||||
LLRect contents;
|
||||
|
||||
// Make sure group_id isn't null
|
||||
if (group_id.isNull())
|
||||
{
|
||||
llwarns << "LLFloaterGroupInvite::showForGroup with null group_id!" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have a floater for this group, create one.
|
||||
LLFloaterGroupBulkBan* fgb = get_if_there(impl::sInstances,
|
||||
group_id,
|
||||
(LLFloaterGroupBulkBan*)NULL);
|
||||
if (!fgb)
|
||||
{
|
||||
fgb = new LLFloaterGroupBulkBan(group_id);
|
||||
contents = fgb->mImpl->mBulkBanPanelp->getRect();
|
||||
contents.mTop += floater_header_size;
|
||||
fgb->setRect(contents);
|
||||
fgb->getDragHandle()->setRect(contents);
|
||||
fgb->getDragHandle()->setTitle(fgb->mImpl->mBulkBanPanelp->getString("GroupBulkBan"));
|
||||
|
||||
impl::sInstances[group_id] = fgb;
|
||||
|
||||
fgb->mImpl->mBulkBanPanelp->clear();
|
||||
}
|
||||
|
||||
if (agent_ids != NULL)
|
||||
{
|
||||
fgb->mImpl->mBulkBanPanelp->addUsers(*agent_ids);
|
||||
}
|
||||
|
||||
fgb->center();
|
||||
fgb->openFloater();
|
||||
fgb->mImpl->mBulkBanPanelp->update();
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* @file llfloatergroupbulkban.h
|
||||
* @brief This floater is a wrapper for LLPanelGroupBulkBan, which
|
||||
* is used to ban Residents from a specific group.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERGROUPBULKBAN_H
|
||||
#define LL_LLFLOATERGROUPBULKBAN_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
class LLFloaterGroupBulkBan : public LLFloater
|
||||
{
|
||||
public:
|
||||
virtual ~LLFloaterGroupBulkBan();
|
||||
|
||||
static void showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids = NULL);
|
||||
|
||||
protected:
|
||||
LLFloaterGroupBulkBan(const LLUUID& group_id = LLUUID::null);
|
||||
|
||||
class impl;
|
||||
impl* mImpl;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERGROUPBULKBAN_H
|
||||
|
|
@ -532,6 +532,7 @@ void LLFloaterIMContainer::draw()
|
|||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID);
|
||||
participant_model->setGroupBanVisible(haveAbilityToBan() && participant_model->getUUID() != gAgentID);
|
||||
|
||||
current_participant_model++;
|
||||
}
|
||||
|
|
@ -1150,6 +1151,10 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
|
|||
{
|
||||
toggleAllowTextChat(userID);
|
||||
}
|
||||
else if ("ban_member" == command)
|
||||
{
|
||||
banSelectedMember(userID);
|
||||
}
|
||||
}
|
||||
else if (selectedIDS.size() > 1)
|
||||
{
|
||||
|
|
@ -1271,6 +1276,22 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
|
|||
uuid_vec_t uuids;
|
||||
getParticipantUUIDs(uuids);
|
||||
|
||||
|
||||
//If there is group or ad-hoc chat in multiselection, everything needs to be disabled
|
||||
if(uuids.size() > 1)
|
||||
{
|
||||
const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList();
|
||||
LLConversationItem * conversationItem;
|
||||
for(std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
|
||||
{
|
||||
conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem());
|
||||
if((conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP) || (conversationItem->getType() == LLConversationItem::CONV_SESSION_AD_HOC))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("conversation_log" == item)
|
||||
{
|
||||
return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
|
||||
|
|
@ -1375,6 +1396,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
|
|||
else if ("can_call" == item)
|
||||
{
|
||||
return LLAvatarActions::canCall();
|
||||
}
|
||||
else if ("can_open_voice_conversation" == item)
|
||||
{
|
||||
return is_single_select && LLAvatarActions::canCall();
|
||||
}
|
||||
else if ("can_zoom_in" == item)
|
||||
{
|
||||
|
|
@ -1387,6 +1412,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
|
|||
else if ("can_offer_teleport" == item)
|
||||
{
|
||||
return LLAvatarActions::canOfferTeleport(uuids);
|
||||
}
|
||||
else if ("can_ban_member" == item)
|
||||
{
|
||||
return canBanSelectedMember(single_id);
|
||||
}
|
||||
else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
|
||||
{
|
||||
|
|
@ -1810,6 +1839,95 @@ bool LLFloaterIMContainer::isGroupModerator()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool LLFloaterIMContainer::haveAbilityToBan()
|
||||
{
|
||||
LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
|
||||
if (NULL == speaker_manager)
|
||||
{
|
||||
LL_WARNS() << "Speaker manager is missing" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
LLUUID group_uuid = speaker_manager->getSessionID();
|
||||
|
||||
return gAgent.isInGroup(group_uuid) && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS);
|
||||
}
|
||||
|
||||
bool LLFloaterIMContainer::canBanSelectedMember(const LLUUID& participant_uuid)
|
||||
{
|
||||
LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
|
||||
if (NULL == speaker_manager)
|
||||
{
|
||||
LL_WARNS() << "Speaker manager is missing" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
LLUUID group_uuid = speaker_manager->getSessionID();
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid);
|
||||
if(!gdatap)
|
||||
{
|
||||
LL_WARNS("Groups") << "Unable to get group data for group " << group_uuid << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gdatap->mMembers.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find((participant_uuid));
|
||||
if (mi == gdatap->mMembers.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterIMContainer::banSelectedMember(const LLUUID& participant_uuid)
|
||||
{
|
||||
LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
|
||||
if (NULL == speaker_manager)
|
||||
{
|
||||
LL_WARNS() << "Speaker manager is missing" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID group_uuid = speaker_manager->getSessionID();
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid);
|
||||
if(!gdatap)
|
||||
{
|
||||
LL_WARNS("Groups") << "Unable to get group data for group " << group_uuid << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
std::vector<LLUUID> ids;
|
||||
ids.push_back(participant_uuid);
|
||||
|
||||
LLGroupBanData ban_data;
|
||||
gdatap->createBanEntry(participant_uuid, ban_data);
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, group_uuid, LLGroupMgr::BAN_CREATE, ids);
|
||||
LLGroupMgr::getInstance()->sendGroupMemberEjects(group_uuid, ids);
|
||||
LLGroupMgr::getInstance()->sendGroupMembersRequest(group_uuid);
|
||||
LLSD args;
|
||||
std::string name;
|
||||
gCacheName->getFullName(participant_uuid, name);
|
||||
args["AVATAR_NAME"] = name;
|
||||
args["GROUP_NAME"] = gdatap->mName;
|
||||
LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
|
||||
|
||||
}
|
||||
|
||||
void LLFloaterIMContainer::moderateVoice(const std::string& command, const LLUUID& userID)
|
||||
{
|
||||
if (!gAgent.getRegion()) return;
|
||||
|
|
|
|||
|
|
@ -167,12 +167,16 @@ private:
|
|||
LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
|
||||
LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
|
||||
bool isGroupModerator();
|
||||
bool haveAbilityToBan();
|
||||
bool canBanSelectedMember(const LLUUID& participant_uuid);
|
||||
LLUUID getGroupUIIDForSelectedParticipant();
|
||||
bool isMuted(const LLUUID& avatar_id);
|
||||
void moderateVoice(const std::string& command, const LLUUID& userID);
|
||||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ public:
|
|||
|
||||
void changed(LLGroupChange gc)
|
||||
{
|
||||
if (gc == GC_MEMBER_DATA && !mRequestProcessed)
|
||||
if (gc == GC_PROPERTIES && !mRequestProcessed)
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId);
|
||||
if (!gdatap)
|
||||
|
|
@ -159,9 +159,6 @@ public:
|
|||
else if (!gdatap->isMemberDataComplete())
|
||||
{
|
||||
LL_WARNS() << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
processGroupData();
|
||||
mRequestProcessed = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,11 +234,11 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) :
|
|||
mMemberCount(0),
|
||||
mRoleCount(0),
|
||||
mReceivedRoleMemberPairs(0),
|
||||
mMemberDataComplete(FALSE),
|
||||
mRoleDataComplete(FALSE),
|
||||
mRoleMemberDataComplete(FALSE),
|
||||
mGroupPropertiesDataComplete(FALSE),
|
||||
mPendingRoleMemberRequest(FALSE),
|
||||
mMemberDataComplete(false),
|
||||
mRoleDataComplete(false),
|
||||
mRoleMemberDataComplete(false),
|
||||
mGroupPropertiesDataComplete(false),
|
||||
mPendingRoleMemberRequest(false),
|
||||
mAccessTime(0.0f)
|
||||
{
|
||||
mMemberVersion.generate();
|
||||
|
|
@ -427,7 +427,7 @@ void LLGroupMgrGroupData::removeMemberData()
|
|||
delete mi->second;
|
||||
}
|
||||
mMembers.clear();
|
||||
mMemberDataComplete = FALSE;
|
||||
mMemberDataComplete = false;
|
||||
mMemberVersion.generate();
|
||||
}
|
||||
|
||||
|
|
@ -449,8 +449,8 @@ void LLGroupMgrGroupData::removeRoleData()
|
|||
}
|
||||
mRoles.clear();
|
||||
mReceivedRoleMemberPairs = 0;
|
||||
mRoleDataComplete = FALSE;
|
||||
mRoleMemberDataComplete = FALSE;
|
||||
mRoleDataComplete = false;
|
||||
mRoleMemberDataComplete= false;
|
||||
}
|
||||
|
||||
void LLGroupMgrGroupData::removeRoleMemberData()
|
||||
|
|
@ -474,7 +474,7 @@ void LLGroupMgrGroupData::removeRoleMemberData()
|
|||
}
|
||||
|
||||
mReceivedRoleMemberPairs = 0;
|
||||
mRoleMemberDataComplete = FALSE;
|
||||
mRoleMemberDataComplete= false;
|
||||
}
|
||||
|
||||
LLGroupMgrGroupData::~LLGroupMgrGroupData()
|
||||
|
|
@ -750,6 +750,20 @@ void LLGroupMgrGroupData::cancelRoleChanges()
|
|||
// Clear out all changes!
|
||||
mRoleChanges.clear();
|
||||
}
|
||||
|
||||
void LLGroupMgrGroupData::createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data)
|
||||
{
|
||||
mBanList[ban_id] = ban_data;
|
||||
}
|
||||
|
||||
void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id)
|
||||
{
|
||||
mBanList.erase(ban_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// LLGroupMgr
|
||||
//
|
||||
|
|
@ -959,12 +973,12 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
|
|||
|
||||
if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount)
|
||||
{
|
||||
group_datap->mMemberDataComplete = TRUE;
|
||||
group_datap->mMemberDataComplete = true;
|
||||
group_datap->mMemberRequestID.setNull();
|
||||
// We don't want to make role-member data requests until we have all the members
|
||||
if (group_datap->mPendingRoleMemberRequest)
|
||||
{
|
||||
group_datap->mPendingRoleMemberRequest = FALSE;
|
||||
group_datap->mPendingRoleMemberRequest = false;
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID);
|
||||
}
|
||||
}
|
||||
|
|
@ -1034,7 +1048,7 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
|
|||
group_datap->mMemberCount = num_group_members;
|
||||
group_datap->mRoleCount = num_group_roles + 1; // Add the everyone role.
|
||||
|
||||
group_datap->mGroupPropertiesDataComplete = TRUE;
|
||||
group_datap->mGroupPropertiesDataComplete = true;
|
||||
group_datap->mChanged = TRUE;
|
||||
|
||||
LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES);
|
||||
|
|
@ -1111,12 +1125,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
|
|||
|
||||
if (group_datap->mRoles.size() == (U32)group_datap->mRoleCount)
|
||||
{
|
||||
group_datap->mRoleDataComplete = TRUE;
|
||||
group_datap->mRoleDataComplete = true;
|
||||
group_datap->mRoleDataRequestID.setNull();
|
||||
// We don't want to make role-member data requests until we have all the role data
|
||||
if (group_datap->mPendingRoleMemberRequest)
|
||||
{
|
||||
group_datap->mPendingRoleMemberRequest = FALSE;
|
||||
group_datap->mPendingRoleMemberRequest = false;
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID);
|
||||
}
|
||||
}
|
||||
|
|
@ -1225,7 +1239,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
|
|||
}
|
||||
}
|
||||
|
||||
group_datap->mRoleMemberDataComplete = TRUE;
|
||||
group_datap->mRoleMemberDataComplete= true;
|
||||
group_datap->mRoleMembersRequestID.setNull();
|
||||
}
|
||||
|
||||
|
|
@ -1848,6 +1862,138 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
|
|||
}
|
||||
|
||||
|
||||
// Responder class for capability group management
|
||||
class GroupBanDataResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false);
|
||||
virtual ~GroupBanDataResponder() {}
|
||||
virtual void httpSuccess();
|
||||
virtual void httpFailure();
|
||||
private:
|
||||
LLUUID mGroupID;
|
||||
BOOL mForceRefresh;
|
||||
};
|
||||
|
||||
GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) :
|
||||
mGroupID(gropup_id),
|
||||
mForceRefresh(force_refresh)
|
||||
{}
|
||||
|
||||
void GroupBanDataResponder::httpFailure()
|
||||
{
|
||||
LL_WARNS("GrpMgr") << "Error receiving group member data [status:"
|
||||
<< mStatus << "]: " << mContent << LL_ENDL;
|
||||
}
|
||||
|
||||
void GroupBanDataResponder::httpSuccess()
|
||||
{
|
||||
if (mContent.has("ban_list"))
|
||||
{
|
||||
// group ban data received
|
||||
LLGroupMgr::processGroupBanRequest(mContent);
|
||||
}
|
||||
else if (mForceRefresh)
|
||||
{
|
||||
// no ban data received, refreshing data after successful operation
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type,
|
||||
const LLUUID& group_id,
|
||||
U32 ban_action, /* = BAN_NO_ACTION */
|
||||
const std::vector<LLUUID> ban_list) /* = std::vector<LLUUID>() */
|
||||
{
|
||||
LLViewerRegion* currentRegion = gAgent.getRegion();
|
||||
if(!currentRegion)
|
||||
{
|
||||
LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to make sure we have our capabilities
|
||||
if(!currentRegion->capabilitiesReceived())
|
||||
{
|
||||
LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get our capability
|
||||
std::string cap_url = currentRegion->getCapability("GroupAPIv1");
|
||||
if(cap_url.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
cap_url += "?group_id=" + group_id.asString();
|
||||
|
||||
LLSD body = LLSD::emptyMap();
|
||||
body["ban_action"] = (LLSD::Integer)(ban_action & ~BAN_UPDATE);
|
||||
// Add our list of potential banned residents to the list
|
||||
body["ban_ids"] = LLSD::emptyArray();
|
||||
LLSD ban_entry;
|
||||
|
||||
uuid_vec_t::const_iterator iter = ban_list.begin();
|
||||
for(;iter != ban_list.end(); ++iter)
|
||||
{
|
||||
ban_entry = (*iter);
|
||||
body["ban_ids"].append(ban_entry);
|
||||
}
|
||||
|
||||
LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(group_id, ban_action & BAN_UPDATE);
|
||||
switch(request_type)
|
||||
{
|
||||
case REQUEST_GET:
|
||||
LLHTTPClient::get(cap_url, grp_ban_responder);
|
||||
break;
|
||||
case REQUEST_POST:
|
||||
LLHTTPClient::post(cap_url, body, grp_ban_responder);
|
||||
break;
|
||||
case REQUEST_PUT:
|
||||
case REQUEST_DEL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLGroupMgr::processGroupBanRequest(const LLSD& content)
|
||||
{
|
||||
// Did we get anything in content?
|
||||
if(!content.size())
|
||||
{
|
||||
LL_WARNS("GrpMgr") << "No group member data received." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID group_id = content["group_id"].asUUID();
|
||||
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id);
|
||||
if (!gdatap)
|
||||
return;
|
||||
|
||||
LLSD::map_const_iterator i = content["ban_list"].beginMap();
|
||||
LLSD::map_const_iterator iEnd = content["ban_list"].endMap();
|
||||
for(;i != iEnd; ++i)
|
||||
{
|
||||
const LLUUID ban_id(i->first);
|
||||
LLSD ban_entry(i->second);
|
||||
|
||||
LLGroupBanData ban_data;
|
||||
if(ban_entry.has("ban_date"))
|
||||
{
|
||||
ban_data.mBanDate = ban_entry["ban_date"].asDate();
|
||||
// TODO: Ban Reason
|
||||
}
|
||||
|
||||
gdatap->createBanEntry(ban_id, ban_data);
|
||||
}
|
||||
|
||||
gdatap->mChanged = TRUE;
|
||||
LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Responder class for capability group management
|
||||
class GroupMemberDataResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
|
|
@ -1941,7 +2087,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
|
|||
if(num_members < 1)
|
||||
return;
|
||||
|
||||
LLUUID group_id = content["group_id"].asUUID();
|
||||
LLUUID group_id = content["group_id"].asUUID();
|
||||
|
||||
LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
|
||||
if(!group_datap)
|
||||
|
|
@ -2008,6 +2154,22 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
|
|||
online_status,
|
||||
is_owner);
|
||||
|
||||
LLGroupMemberData* member_old = group_datap->mMembers[member_id];
|
||||
if (member_old && group_datap->mRoleMemberDataComplete)
|
||||
{
|
||||
LLGroupMemberData::role_list_t::iterator rit = member_old->roleBegin();
|
||||
LLGroupMemberData::role_list_t::iterator end = member_old->roleEnd();
|
||||
|
||||
for ( ; rit != end; ++rit)
|
||||
{
|
||||
data->addRole((*rit).first,(*rit).second);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
group_datap->mRoleMemberDataComplete = false;
|
||||
}
|
||||
|
||||
group_datap->mMembers[member_id] = data;
|
||||
}
|
||||
|
||||
|
|
@ -2024,12 +2186,12 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
|
|||
LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
|
||||
|
||||
|
||||
group_datap->mMemberDataComplete = TRUE;
|
||||
group_datap->mMemberDataComplete = true;
|
||||
group_datap->mMemberRequestID.setNull();
|
||||
// Make the role-member data request
|
||||
if (group_datap->mPendingRoleMemberRequest)
|
||||
if (group_datap->mPendingRoleMemberRequest || !group_datap->mRoleMemberDataComplete)
|
||||
{
|
||||
group_datap->mPendingRoleMemberRequest = FALSE;
|
||||
group_datap->mPendingRoleMemberRequest = false;
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,10 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// Forward Declarations
|
||||
class LLMessageSystem;
|
||||
|
||||
class LLGroupRoleData;
|
||||
class LLGroupMgr;
|
||||
|
||||
enum LLGroupChange
|
||||
{
|
||||
|
|
@ -43,9 +45,12 @@ enum LLGroupChange
|
|||
GC_ROLE_DATA,
|
||||
GC_ROLE_MEMBER_DATA,
|
||||
GC_TITLES,
|
||||
GC_BANLIST,
|
||||
GC_ALL
|
||||
};
|
||||
|
||||
const U32 GB_MAX_BANNED_AGENTS = 500;
|
||||
|
||||
class LLGroupMgrObserver
|
||||
{
|
||||
public:
|
||||
|
|
@ -65,8 +70,6 @@ public:
|
|||
virtual void changed(const LLUUID& group_id, LLGroupChange gc) = 0;
|
||||
};
|
||||
|
||||
class LLGroupRoleData;
|
||||
|
||||
class LLGroupMemberData
|
||||
{
|
||||
friend class LLGroupMgrGroupData;
|
||||
|
|
@ -201,6 +204,17 @@ struct lluuid_pair_less
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
struct LLGroupBanData
|
||||
{
|
||||
LLGroupBanData(): mBanDate() {}
|
||||
~LLGroupBanData() {}
|
||||
|
||||
LLDate mBanDate;
|
||||
// TODO: std:string ban_reason;
|
||||
};
|
||||
|
||||
|
||||
struct LLGroupTitle
|
||||
{
|
||||
std::string mTitle;
|
||||
|
|
@ -208,8 +222,6 @@ struct LLGroupTitle
|
|||
BOOL mSelected;
|
||||
};
|
||||
|
||||
class LLGroupMgr;
|
||||
|
||||
class LLGroupMgrGroupData
|
||||
{
|
||||
friend class LLGroupMgr;
|
||||
|
|
@ -239,11 +251,11 @@ public:
|
|||
void recalcAllAgentPowers();
|
||||
void recalcAgentPowers(const LLUUID& agent_id);
|
||||
|
||||
BOOL isMemberDataComplete() { return mMemberDataComplete; }
|
||||
BOOL isRoleDataComplete() { return mRoleDataComplete; }
|
||||
BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; }
|
||||
BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; }
|
||||
|
||||
bool isMemberDataComplete() { return mMemberDataComplete; }
|
||||
bool isRoleDataComplete() { return mRoleDataComplete; }
|
||||
bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; }
|
||||
bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; }
|
||||
|
||||
bool isSingleMemberNotOwner();
|
||||
|
||||
F32 getAccessTime() const { return mAccessTime; }
|
||||
|
|
@ -251,17 +263,26 @@ public:
|
|||
|
||||
const LLUUID& getMemberVersion() const { return mMemberVersion; }
|
||||
|
||||
void clearBanList() { mBanList.clear(); }
|
||||
void getBanList(const LLUUID& group_id, LLGroupBanData& ban_data);
|
||||
const LLGroupBanData& getBanEntry(const LLUUID& ban_id) { return mBanList[ban_id]; }
|
||||
|
||||
void createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data = LLGroupBanData());
|
||||
void removeBanEntry(const LLUUID& ban_id);
|
||||
|
||||
|
||||
public:
|
||||
typedef std::map<LLUUID,LLGroupMemberData*> member_list_t;
|
||||
typedef std::map<LLUUID,LLGroupRoleData*> role_list_t;
|
||||
typedef std::map<lluuid_pair,LLRoleMemberChange,lluuid_pair_less> change_map_t;
|
||||
typedef std::map<LLUUID,LLRoleData> role_data_map_t;
|
||||
typedef std::map<LLUUID,LLGroupBanData> ban_list_t;
|
||||
|
||||
member_list_t mMembers;
|
||||
role_list_t mRoles;
|
||||
|
||||
|
||||
change_map_t mRoleMemberChanges;
|
||||
role_data_map_t mRoleChanges;
|
||||
ban_list_t mBanList;
|
||||
|
||||
std::vector<LLGroupTitle> mTitles;
|
||||
|
||||
|
|
@ -292,12 +313,12 @@ private:
|
|||
LLUUID mTitlesRequestID;
|
||||
U32 mReceivedRoleMemberPairs;
|
||||
|
||||
BOOL mMemberDataComplete;
|
||||
BOOL mRoleDataComplete;
|
||||
BOOL mRoleMemberDataComplete;
|
||||
BOOL mGroupPropertiesDataComplete;
|
||||
bool mMemberDataComplete;
|
||||
bool mRoleDataComplete;
|
||||
bool mRoleMemberDataComplete;
|
||||
bool mGroupPropertiesDataComplete;
|
||||
|
||||
BOOL mPendingRoleMemberRequest;
|
||||
bool mPendingRoleMemberRequest;
|
||||
F32 mAccessTime;
|
||||
|
||||
// Generate a new ID every time mMembers
|
||||
|
|
@ -324,6 +345,23 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
|
|||
{
|
||||
LOG_CLASS(LLGroupMgr);
|
||||
|
||||
public:
|
||||
enum EBanRequestType
|
||||
{
|
||||
REQUEST_GET = 0,
|
||||
REQUEST_POST,
|
||||
REQUEST_PUT,
|
||||
REQUEST_DEL
|
||||
};
|
||||
|
||||
enum EBanRequestAction
|
||||
{
|
||||
BAN_NO_ACTION = 0,
|
||||
BAN_CREATE = 1,
|
||||
BAN_DELETE = 2,
|
||||
BAN_UPDATE = 4
|
||||
};
|
||||
|
||||
public:
|
||||
LLGroupMgr();
|
||||
~LLGroupMgr();
|
||||
|
|
@ -357,8 +395,14 @@ public:
|
|||
static void sendGroupMemberInvites(const LLUUID& group_id, std::map<LLUUID,LLUUID>& role_member_pairs);
|
||||
static void sendGroupMemberEjects(const LLUUID& group_id,
|
||||
uuid_vec_t& member_ids);
|
||||
|
||||
static void sendGroupBanRequest(EBanRequestType request_type,
|
||||
const LLUUID& group_id,
|
||||
U32 ban_action = BAN_NO_ACTION,
|
||||
const uuid_vec_t ban_list = uuid_vec_t());
|
||||
|
||||
static void processGroupBanRequest(const LLSD& content);
|
||||
|
||||
// BAKER
|
||||
void sendCapGroupMembersRequest(const LLUUID& group_id);
|
||||
static void processCapGroupMembersRequest(const LLSD& content);
|
||||
|
||||
|
|
@ -403,4 +447,3 @@ private:
|
|||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
|
|||
mNameColumnIndex(p.name_column.column_index),
|
||||
mNameColumn(p.name_column.column_name),
|
||||
mAllowCallingCardDrop(p.allow_calling_card_drop),
|
||||
mShortNames(p.short_names)
|
||||
mShortNames(p.short_names),
|
||||
mPendingLookupsRemaining(0)
|
||||
{}
|
||||
|
||||
// public
|
||||
|
|
@ -337,6 +338,17 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
|||
mAvatarNameCacheConnections.erase(it);
|
||||
}
|
||||
mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle()));
|
||||
|
||||
if(mPendingLookupsRemaining <= 0)
|
||||
{
|
||||
// BAKER TODO:
|
||||
// We might get into a state where mPendingLookupsRemaining might
|
||||
// go negative. So just reset it right now and figure out if it's
|
||||
// possible later :)
|
||||
mPendingLookupsRemaining = 0;
|
||||
mNameListCompleteSignal(false);
|
||||
}
|
||||
mPendingLookupsRemaining++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -388,6 +400,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
|
|||
{
|
||||
selectNthItem(idx); // not sure whether this is needed, taken from previous implementation
|
||||
deleteSingleItem(idx);
|
||||
|
||||
mPendingLookupsRemaining--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -429,6 +443,23 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
|
|||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// BAKER - FIX NameListCtrl
|
||||
//if (mPendingLookupsRemaining <= 0)
|
||||
{
|
||||
// We might get into a state where mPendingLookupsRemaining might
|
||||
// go negative. So just reset it right now and figure out if it's
|
||||
// possible later :)
|
||||
//mPendingLookupsRemaining = 0;
|
||||
|
||||
mNameListCompleteSignal(true);
|
||||
}
|
||||
//else
|
||||
{
|
||||
// mPendingLookupsRemaining--;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dirtyColumns();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ class LLNameListCtrl
|
|||
: public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl>
|
||||
{
|
||||
public:
|
||||
typedef boost::signals2::signal<void(bool)> namelist_complete_signal_t;
|
||||
|
||||
typedef enum e_name_type
|
||||
{
|
||||
|
|
@ -156,7 +157,7 @@ public:
|
|||
|
||||
/*virtual*/ void updateColumns(bool force_update);
|
||||
|
||||
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
|
||||
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
|
||||
private:
|
||||
void showInspector(const LLUUID& avatar_id, bool is_group);
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle<LLNameListItem> item);
|
||||
|
|
@ -168,6 +169,16 @@ private:
|
|||
bool mShortNames; // display name only, no SLID
|
||||
typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
|
||||
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
|
||||
|
||||
S32 mPendingLookupsRemaining;
|
||||
namelist_complete_signal_t mNameListCompleteSignal;
|
||||
|
||||
public:
|
||||
boost::signals2::connection setOnNameListCompleteCallback(boost::function<void(bool)> onNameListCompleteCallback)
|
||||
{
|
||||
return mNameListCompleteSignal.connect(onNameListCompleteCallback);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,421 @@
|
|||
/**
|
||||
* @file llpanelgroupbulk.cpp
|
||||
* @brief Implementation of llpanelgroupbulk
|
||||
* @author Baker@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelgroupbulk.h"
|
||||
#include "llpanelgroupbulkimpl.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llfloateravatarpicker.h"
|
||||
#include "llbutton.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "llgroupmgr.h"
|
||||
#include "llnamelistctrl.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llscrolllistitem.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of llpanelgroupbulkimpl.h functions
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) :
|
||||
mGroupID(group_id),
|
||||
mBulkAgentList(NULL),
|
||||
mOKButton(NULL),
|
||||
mRemoveButton(NULL),
|
||||
mGroupName(NULL),
|
||||
mLoadingText(),
|
||||
mTooManySelected(),
|
||||
mCloseCallback(NULL),
|
||||
mCloseCallbackUserData(NULL),
|
||||
mAvatarNameCacheConnection(),
|
||||
mRoleNames(NULL),
|
||||
mOwnerWarning(),
|
||||
mAlreadyInGroup(),
|
||||
mConfirmedOwnerInvite(false),
|
||||
mListFullNotificationSent(false)
|
||||
{}
|
||||
|
||||
LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl()
|
||||
{
|
||||
if(mAvatarNameCacheConnection.connected())
|
||||
{
|
||||
mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata)
|
||||
{
|
||||
LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata;
|
||||
|
||||
if(panelp)
|
||||
{
|
||||
//Right now this is hard coded with some knowledge that it is part
|
||||
//of a floater since the avatar picker needs to be added as a dependent
|
||||
//floater to the parent floater.
|
||||
//Soon the avatar picker will be embedded into this panel
|
||||
//instead of being it's own separate floater. But that is next week.
|
||||
//This will do for now. -jwolk May 10, 2006
|
||||
LLView* button = panelp->findChild<LLButton>("add_button");
|
||||
LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
|
||||
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
|
||||
boost::bind(callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button);
|
||||
if(picker)
|
||||
{
|
||||
root_floater->addDependentFloater(picker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::callbackClickRemove(void* userdata)
|
||||
{
|
||||
LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata;
|
||||
if (selfp)
|
||||
selfp->handleRemove();
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::callbackClickCancel(void* userdata)
|
||||
{
|
||||
LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata;
|
||||
if(selfp)
|
||||
(*(selfp->mCloseCallback))(selfp->mCloseCallbackUserData);
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::callbackSelect(LLUICtrl* ctrl, void* userdata)
|
||||
{
|
||||
LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata;
|
||||
if (selfp)
|
||||
selfp->handleSelection();
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data)
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
for (S32 i = 0; i < (S32)agent_ids.size(); i++)
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
if (LLAvatarNameCache::get(agent_ids[i], &av_name))
|
||||
{
|
||||
onAvatarNameCache(agent_ids[i], av_name, user_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data;
|
||||
if (selfp)
|
||||
{
|
||||
if (selfp->mAvatarNameCacheConnection.connected())
|
||||
{
|
||||
selfp->mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
// *TODO : Add a callback per avatar name being fetched.
|
||||
selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(onAvatarNameCache, _1, _2, user_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data)
|
||||
{
|
||||
LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data;
|
||||
|
||||
if (selfp)
|
||||
{
|
||||
if (selfp->mAvatarNameCacheConnection.connected())
|
||||
{
|
||||
selfp->mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
std::vector<std::string> names;
|
||||
uuid_vec_t agent_ids;
|
||||
agent_ids.push_back(agent_id);
|
||||
names.push_back(av_name.getCompleteName());
|
||||
|
||||
selfp->addUsers(names, agent_ids);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::handleRemove()
|
||||
{
|
||||
std::vector<LLScrollListItem*> selection = mBulkAgentList->getAllSelected();
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
std::vector<LLScrollListItem*>::iterator iter;
|
||||
for(iter = selection.begin(); iter != selection.end(); ++iter)
|
||||
{
|
||||
mInviteeIDs.erase((*iter)->getUUID());
|
||||
}
|
||||
|
||||
mBulkAgentList->deleteSelectedItems();
|
||||
mRemoveButton->setEnabled(FALSE);
|
||||
|
||||
if( mOKButton && mOKButton->getEnabled() &&
|
||||
mBulkAgentList->isEmpty())
|
||||
{
|
||||
mOKButton->setEnabled(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::handleSelection()
|
||||
{
|
||||
std::vector<LLScrollListItem*> selection = mBulkAgentList->getAllSelected();
|
||||
if (selection.empty())
|
||||
mRemoveButton->setEnabled(FALSE);
|
||||
else
|
||||
mRemoveButton->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::addUsers(const std::vector<std::string>& names, const uuid_vec_t& agent_ids)
|
||||
{
|
||||
std::string name;
|
||||
LLUUID id;
|
||||
|
||||
if(mListFullNotificationSent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !mListFullNotificationSent &&
|
||||
(names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES))
|
||||
{
|
||||
mListFullNotificationSent = true;
|
||||
|
||||
// Fail! Show a warning and don't add any names.
|
||||
LLSD msg;
|
||||
msg["MESSAGE"] = mTooManySelected;
|
||||
LLNotificationsUtil::add("GenericAlert", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < (S32)names.size(); ++i)
|
||||
{
|
||||
name = names[i];
|
||||
id = agent_ids[i];
|
||||
|
||||
if(mInviteeIDs.find(id) != mInviteeIDs.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//add the name to the names list
|
||||
LLSD row;
|
||||
row["id"] = id;
|
||||
row["columns"][0]["value"] = name;
|
||||
|
||||
mBulkAgentList->addElement(row);
|
||||
mInviteeIDs.insert(id);
|
||||
|
||||
// We've successfully added someone to the list.
|
||||
if(mOKButton && !mOKButton->getEnabled())
|
||||
mOKButton->setEnabled(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::setGroupName(std::string name)
|
||||
{
|
||||
if(mGroupName)
|
||||
mGroupName->setText(name);
|
||||
}
|
||||
|
||||
|
||||
LLPanelGroupBulk::LLPanelGroupBulk(const LLUUID& group_id) :
|
||||
LLPanel(),
|
||||
mImplementation(new LLPanelGroupBulkImpl(group_id)),
|
||||
mPendingGroupPropertiesUpdate(false),
|
||||
mPendingRoleDataUpdate(false),
|
||||
mPendingMemberDataUpdate(false)
|
||||
{}
|
||||
|
||||
LLPanelGroupBulk::~LLPanelGroupBulk()
|
||||
{
|
||||
delete mImplementation;
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::clear()
|
||||
{
|
||||
mImplementation->mInviteeIDs.clear();
|
||||
|
||||
if(mImplementation->mBulkAgentList)
|
||||
mImplementation->mBulkAgentList->deleteAllItems();
|
||||
|
||||
if(mImplementation->mOKButton)
|
||||
mImplementation->mOKButton->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::update()
|
||||
{
|
||||
updateGroupName();
|
||||
updateGroupData();
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::draw()
|
||||
{
|
||||
LLPanel::draw();
|
||||
update();
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::updateGroupName()
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID);
|
||||
|
||||
if( gdatap &&
|
||||
gdatap->isGroupPropertiesDataComplete())
|
||||
{
|
||||
// Only do work if the current group name differs
|
||||
if(mImplementation->mGroupName->getText().compare(gdatap->mName) != 0)
|
||||
mImplementation->setGroupName(gdatap->mName);
|
||||
}
|
||||
else
|
||||
{
|
||||
mImplementation->setGroupName(mImplementation->mLoadingText);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::updateGroupData()
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID);
|
||||
if(gdatap && gdatap->isGroupPropertiesDataComplete())
|
||||
{
|
||||
mPendingGroupPropertiesUpdate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!mPendingGroupPropertiesUpdate)
|
||||
{
|
||||
mPendingGroupPropertiesUpdate = true;
|
||||
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
|
||||
}
|
||||
}
|
||||
|
||||
if(gdatap && gdatap->isRoleDataComplete())
|
||||
{
|
||||
mPendingRoleDataUpdate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!mPendingRoleDataUpdate)
|
||||
{
|
||||
mPendingRoleDataUpdate = true;
|
||||
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
|
||||
}
|
||||
}
|
||||
|
||||
if(gdatap && gdatap->isMemberDataComplete())
|
||||
{
|
||||
mPendingMemberDataUpdate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!mPendingMemberDataUpdate)
|
||||
{
|
||||
mPendingMemberDataUpdate = true;
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::addUserCallback(const LLUUID& id, const LLAvatarName& av_name)
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
uuid_vec_t agent_ids;
|
||||
agent_ids.push_back(id);
|
||||
names.push_back(av_name.getAccountName());
|
||||
|
||||
mImplementation->addUsers(names, agent_ids);
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::setCloseCallback(void (*close_callback)(void*), void* data)
|
||||
{
|
||||
mImplementation->mCloseCallback = close_callback;
|
||||
mImplementation->mCloseCallbackUserData = data;
|
||||
}
|
||||
|
||||
void LLPanelGroupBulk::addUsers(uuid_vec_t& agent_ids)
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
for (S32 i = 0; i < (S32)agent_ids.size(); i++)
|
||||
{
|
||||
std::string fullname;
|
||||
LLUUID agent_id = agent_ids[i];
|
||||
LLViewerObject* dest = gObjectList.findObject(agent_id);
|
||||
if(dest && dest->isAvatar())
|
||||
{
|
||||
LLNameValue* nvfirst = dest->getNVPair("FirstName");
|
||||
LLNameValue* nvlast = dest->getNVPair("LastName");
|
||||
if(nvfirst && nvlast)
|
||||
{
|
||||
fullname = LLCacheName::buildFullName(
|
||||
nvfirst->getString(), nvlast->getString());
|
||||
|
||||
}
|
||||
if (!fullname.empty())
|
||||
{
|
||||
names.push_back(fullname);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "llPanelGroupBulk: Selected avatar has no name: " << dest->getID() << llendl;
|
||||
names.push_back("(Unknown)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//looks like user try to invite offline friend
|
||||
//for offline avatar_id gObjectList.findObject() will return null
|
||||
//so we need to do this additional search in avatar tracker, see EXT-4732
|
||||
if (LLAvatarTracker::instance().isBuddy(agent_id))
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
if (!LLAvatarNameCache::get(agent_id, &av_name))
|
||||
{
|
||||
// actually it should happen, just in case
|
||||
LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupBulk::addUserCallback, this, _1, _2));
|
||||
// for this special case!
|
||||
//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence
|
||||
// removed id will be added in callback
|
||||
agent_ids.erase(agent_ids.begin() + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
names.push_back(av_name.getAccountName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mImplementation->mListFullNotificationSent = false;
|
||||
mImplementation->addUsers(names, agent_ids);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* @file llpanelgroupbulk.h
|
||||
* @brief Header file for llpanelgroupbulk
|
||||
* @author Baker@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef LL_LLPANELGROUPBULK_H
|
||||
#define LL_LLPANELGROUPBULK_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
class LLAvatarName;
|
||||
class LLGroupMgrGroupData;
|
||||
class LLPanelGroupBulkImpl;
|
||||
|
||||
// Base panel class for bulk group invite / ban floaters
|
||||
class LLPanelGroupBulk : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelGroupBulk(const LLUUID& group_id);
|
||||
/*virtual*/ ~LLPanelGroupBulk();
|
||||
|
||||
public:
|
||||
static void callbackClickSubmit(void* userdata) {}
|
||||
virtual void submit() = 0;
|
||||
|
||||
public:
|
||||
virtual void clear();
|
||||
virtual void update();
|
||||
virtual void draw();
|
||||
|
||||
protected:
|
||||
virtual void updateGroupName();
|
||||
virtual void updateGroupData();
|
||||
|
||||
public:
|
||||
// this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers().
|
||||
virtual void addUserCallback(const LLUUID& id, const LLAvatarName& av_name);
|
||||
virtual void setCloseCallback(void (*close_callback)(void*), void* data);
|
||||
|
||||
virtual void addUsers(uuid_vec_t& agent_ids);
|
||||
|
||||
public:
|
||||
LLPanelGroupBulkImpl* mImplementation;
|
||||
|
||||
protected:
|
||||
bool mPendingGroupPropertiesUpdate;
|
||||
bool mPendingRoleDataUpdate;
|
||||
bool mPendingMemberDataUpdate;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELGROUPBULK_H
|
||||
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/**
|
||||
* @file llpanelgroupbulkban.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelgroupbulkban.h"
|
||||
#include "llpanelgroupbulk.h"
|
||||
#include "llpanelgroupbulkimpl.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llfloateravatarpicker.h"
|
||||
#include "llbutton.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "llgroupmgr.h"
|
||||
#include "llnamelistctrl.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llscrolllistitem.h"
|
||||
#include "llslurl.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
LLPanelGroupBulkBan::LLPanelGroupBulkBan(const LLUUID& group_id) : LLPanelGroupBulk(group_id)
|
||||
{
|
||||
// Pass on construction of this panel to the control factory.
|
||||
buildFromFile( "panel_group_bulk_ban.xml");
|
||||
}
|
||||
|
||||
BOOL LLPanelGroupBulkBan::postBuild()
|
||||
{
|
||||
BOOL recurse = TRUE;
|
||||
|
||||
mImplementation->mLoadingText = getString("loading");
|
||||
mImplementation->mGroupName = getChild<LLTextBox>("group_name_text", recurse);
|
||||
mImplementation->mBulkAgentList = getChild<LLNameListCtrl>("banned_agent_list", recurse);
|
||||
if ( mImplementation->mBulkAgentList )
|
||||
{
|
||||
mImplementation->mBulkAgentList->setCommitOnSelectionChange(TRUE);
|
||||
mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation);
|
||||
}
|
||||
|
||||
LLButton* button = getChild<LLButton>("add_button", recurse);
|
||||
if ( button )
|
||||
{
|
||||
// default to opening avatarpicker automatically
|
||||
// (*impl::callbackClickAdd)((void*)this);
|
||||
button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this);
|
||||
}
|
||||
|
||||
mImplementation->mRemoveButton =
|
||||
getChild<LLButton>("remove_button", recurse);
|
||||
if ( mImplementation->mRemoveButton )
|
||||
{
|
||||
mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation);
|
||||
mImplementation->mRemoveButton->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
mImplementation->mOKButton =
|
||||
getChild<LLButton>("ban_button", recurse);
|
||||
if ( mImplementation->mOKButton )
|
||||
{
|
||||
mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this);
|
||||
mImplementation->mOKButton->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
button = getChild<LLButton>("cancel_button", recurse);
|
||||
if ( button )
|
||||
{
|
||||
button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
|
||||
}
|
||||
|
||||
mImplementation->mTooManySelected = getString("ban_selection_too_large");
|
||||
mImplementation->mBanNotPermitted = getString("ban_not_permitted");
|
||||
mImplementation->mBanLimitFail = getString("ban_limit_fail");
|
||||
mImplementation->mCannotBanYourself = getString("cant_ban_yourself");
|
||||
|
||||
update();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// TODO: Refactor the shitty callback functions with void* -- just use boost::bind to call submit() instead.
|
||||
void LLPanelGroupBulkBan::callbackClickSubmit(void* userdata)
|
||||
{
|
||||
LLPanelGroupBulkBan* selfp = (LLPanelGroupBulkBan*)userdata;
|
||||
|
||||
if(selfp)
|
||||
selfp->submit();
|
||||
}
|
||||
|
||||
|
||||
void LLPanelGroupBulkBan::submit()
|
||||
{
|
||||
if (!gAgent.hasPowerInGroup(mImplementation->mGroupID, GP_GROUP_BAN_ACCESS))
|
||||
{
|
||||
// Fail! Agent no longer have ban rights. Permissions could have changed after button was pressed.
|
||||
LLSD msg;
|
||||
msg["MESSAGE"] = mImplementation->mBanNotPermitted;
|
||||
LLNotificationsUtil::add("GenericAlert", msg);
|
||||
(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);
|
||||
return;
|
||||
}
|
||||
LLGroupMgrGroupData * group_datap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID);
|
||||
if (group_datap && group_datap->mBanList.size() >= GB_MAX_BANNED_AGENTS)
|
||||
{
|
||||
// Fail! Size limit exceeded. List could have updated after button was pressed.
|
||||
LLSD msg;
|
||||
msg["MESSAGE"] = mImplementation->mBanLimitFail;
|
||||
LLNotificationsUtil::add("GenericAlert", msg);
|
||||
(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);
|
||||
return;
|
||||
}
|
||||
std::vector<LLUUID> banned_agent_list;
|
||||
std::vector<LLScrollListItem*> agents = mImplementation->mBulkAgentList->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator iter = agents.begin();
|
||||
for(;iter != agents.end(); ++iter)
|
||||
{
|
||||
LLScrollListItem* agent = *iter;
|
||||
banned_agent_list.push_back(agent->getUUID());
|
||||
}
|
||||
|
||||
const S32 MAX_BANS_PER_REQUEST = 100; // Max bans per request. 100 to match server cap.
|
||||
if (banned_agent_list.size() > MAX_BANS_PER_REQUEST)
|
||||
{
|
||||
// Fail!
|
||||
LLSD msg;
|
||||
msg["MESSAGE"] = mImplementation->mTooManySelected;
|
||||
LLNotificationsUtil::add("GenericAlert", msg);
|
||||
(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);
|
||||
return;
|
||||
}
|
||||
|
||||
// remove already banned users and yourself from request.
|
||||
std::vector<LLAvatarName> banned_avatar_names;
|
||||
std::vector<LLAvatarName> out_of_limit_names;
|
||||
bool banning_self = FALSE;
|
||||
std::vector<LLUUID>::iterator conflict = std::find(banned_agent_list.begin(), banned_agent_list.end(), gAgent.getID());
|
||||
if (conflict != banned_agent_list.end())
|
||||
{
|
||||
banned_agent_list.erase(conflict);
|
||||
banning_self = TRUE;
|
||||
}
|
||||
if (group_datap)
|
||||
{
|
||||
BOOST_FOREACH(const LLGroupMgrGroupData::ban_list_t::value_type& group_ban_pair, group_datap->mBanList)
|
||||
{
|
||||
const LLUUID& group_ban_agent_id = group_ban_pair.first;
|
||||
std::vector<LLUUID>::iterator conflict = std::find(banned_agent_list.begin(), banned_agent_list.end(), group_ban_agent_id);
|
||||
if (conflict != banned_agent_list.end())
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get(group_ban_agent_id, &av_name);
|
||||
banned_avatar_names.push_back(av_name);
|
||||
|
||||
banned_agent_list.erase(conflict);
|
||||
if (banned_agent_list.size() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// this check should always be the last one before we send the request.
|
||||
// Otherwise we have a possibility of cutting more then we need to.
|
||||
if (banned_agent_list.size() > GB_MAX_BANNED_AGENTS - group_datap->mBanList.size())
|
||||
{
|
||||
std::vector<LLUUID>::iterator exeedes_limit = banned_agent_list.begin() + GB_MAX_BANNED_AGENTS - group_datap->mBanList.size();
|
||||
for (std::vector<LLUUID>::iterator itor = exeedes_limit ;
|
||||
itor != banned_agent_list.end(); ++itor)
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get(*itor, &av_name);
|
||||
out_of_limit_names.push_back(av_name);
|
||||
}
|
||||
banned_agent_list.erase(exeedes_limit,banned_agent_list.end());
|
||||
}
|
||||
}
|
||||
|
||||
// sending request and ejecting members
|
||||
if (banned_agent_list.size() != 0)
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mImplementation->mGroupID, LLGroupMgr::BAN_CREATE | LLGroupMgr::BAN_UPDATE, banned_agent_list);
|
||||
LLGroupMgr::getInstance()->sendGroupMemberEjects(mImplementation->mGroupID, banned_agent_list);
|
||||
}
|
||||
|
||||
// building notification
|
||||
if (banned_avatar_names.size() > 0 || banning_self || out_of_limit_names.size() > 0)
|
||||
{
|
||||
std::string reasons;
|
||||
if(banned_avatar_names.size() > 0)
|
||||
{
|
||||
reasons = "\n " + buildResidentsArgument(banned_avatar_names, "residents_already_banned");
|
||||
}
|
||||
|
||||
if(banning_self)
|
||||
{
|
||||
reasons += "\n " + mImplementation->mCannotBanYourself;
|
||||
}
|
||||
|
||||
if(out_of_limit_names.size() > 0)
|
||||
{
|
||||
reasons += "\n " + buildResidentsArgument(out_of_limit_names, "ban_limit_reached");
|
||||
}
|
||||
|
||||
LLStringUtil::format_map_t msg_args;
|
||||
msg_args["[REASONS]"] = reasons;
|
||||
LLSD msg;
|
||||
if (banned_agent_list.size() == 0)
|
||||
{
|
||||
msg["MESSAGE"] = getString("ban_failed", msg_args);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg["MESSAGE"] = getString("partial_ban", msg_args);
|
||||
}
|
||||
LLNotificationsUtil::add("GenericAlert", msg);
|
||||
}
|
||||
|
||||
//then close
|
||||
(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);
|
||||
}
|
||||
|
||||
std::string LLPanelGroupBulkBan::buildResidentsArgument(std::vector<LLAvatarName> avatar_names, const std::string &format)
|
||||
{
|
||||
std::string names_string;
|
||||
LLAvatarActions::buildResidentsString(avatar_names, names_string);
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[RESIDENTS]"] = names_string;
|
||||
return getString(format, args);
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* @file llpanelgroupbulkban.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELGROUPBULKBAN_H
|
||||
#define LL_LLPANELGROUPBULKBAN_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "lluuid.h"
|
||||
#include "llpanelgroupbulk.h"
|
||||
|
||||
class LLAvatarName;
|
||||
|
||||
class LLPanelGroupBulkBan : public LLPanelGroupBulk
|
||||
{
|
||||
public:
|
||||
LLPanelGroupBulkBan(const LLUUID& group_id);
|
||||
~LLPanelGroupBulkBan() {}
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
||||
static void callbackClickSubmit(void* userdata);
|
||||
virtual void submit();
|
||||
private:
|
||||
std::string buildResidentsArgument(std::vector<LLAvatarName> avatar_names, const std::string &format);
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELGROUPBULKBAN_H
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* @file llpanelgroupbulkimpl.h
|
||||
* @brief Class definition for implementation class of LLPanelGroupBulk
|
||||
* @author Baker@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef LL_LLPANELGROUPBULKIMPL_H
|
||||
#define LL_LLPANELGROUPBULKIMPL_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
class LLAvatarName;
|
||||
class LLNameListCtrl;
|
||||
class LLTextBox;
|
||||
class LLComboBox;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Implementation found in llpanelgroupbulk.cpp
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class LLPanelGroupBulkImpl
|
||||
{
|
||||
public:
|
||||
LLPanelGroupBulkImpl(const LLUUID& group_id);
|
||||
~LLPanelGroupBulkImpl();
|
||||
|
||||
static void callbackClickAdd(void* userdata);
|
||||
static void callbackClickRemove(void* userdata);
|
||||
|
||||
static void callbackClickCancel(void* userdata);
|
||||
|
||||
static void callbackSelect(LLUICtrl* ctrl, void* userdata);
|
||||
static void callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data);
|
||||
|
||||
static void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data);
|
||||
|
||||
void handleRemove();
|
||||
void handleSelection();
|
||||
|
||||
void addUsers(const std::vector<std::string>& names, const uuid_vec_t& agent_ids);
|
||||
void setGroupName(std::string name);
|
||||
|
||||
|
||||
public:
|
||||
static const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap.
|
||||
|
||||
|
||||
LLUUID mGroupID;
|
||||
|
||||
LLNameListCtrl* mBulkAgentList;
|
||||
LLButton* mOKButton;
|
||||
LLButton* mRemoveButton;
|
||||
LLTextBox* mGroupName;
|
||||
|
||||
std::string mLoadingText;
|
||||
std::string mTooManySelected;
|
||||
std::string mBanNotPermitted;
|
||||
std::string mBanLimitFail;
|
||||
std::string mCannotBanYourself;
|
||||
|
||||
std::set<LLUUID> mInviteeIDs;
|
||||
|
||||
void (*mCloseCallback)(void* data);
|
||||
void* mCloseCallbackUserData;
|
||||
boost::signals2::connection mAvatarNameCacheConnection;
|
||||
|
||||
// The following are for the LLPanelGroupInvite subclass only.
|
||||
// These aren't needed for LLPanelGroupBulkBan, but if we have to add another
|
||||
// group bulk floater for some reason, we'll have these objects too.
|
||||
public:
|
||||
LLComboBox* mRoleNames;
|
||||
std::string mOwnerWarning;
|
||||
std::string mAlreadyInGroup;
|
||||
bool mConfirmedOwnerInvite;
|
||||
bool mListFullNotificationSent;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELGROUPBULKIMPL_H
|
||||
|
||||
|
|
@ -260,7 +260,7 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap)
|
|||
//else if they have the limited add to roles power
|
||||
//we add every role the user is in
|
||||
//else we just add to everyone
|
||||
bool is_owner = member_data->isInRole(gdatap->mOwnerRole);
|
||||
bool is_owner = member_data->isOwner();
|
||||
bool can_assign_any = gAgent.hasPowerInGroup(mGroupID,
|
||||
GP_ROLE_ASSIGN_MEMBER);
|
||||
bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID,
|
||||
|
|
@ -492,7 +492,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << LL_ENDL;
|
||||
llwarns << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << llendl;
|
||||
names.push_back("(Unknown)");
|
||||
}
|
||||
}
|
||||
|
|
@ -579,7 +579,7 @@ void LLPanelGroupInvite::updateLists()
|
|||
{
|
||||
waiting = true;
|
||||
}
|
||||
if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete())
|
||||
if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && gdatap->isRoleMemberDataComplete())
|
||||
{
|
||||
if ( mImplementation->mRoleNames )
|
||||
{
|
||||
|
|
@ -607,6 +607,7 @@ void LLPanelGroupInvite::updateLists()
|
|||
{
|
||||
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
|
||||
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID);
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
|
||||
}
|
||||
mPendingUpdate = TRUE;
|
||||
|
|
@ -654,7 +655,7 @@ BOOL LLPanelGroupInvite::postBuild()
|
|||
}
|
||||
|
||||
mImplementation->mOKButton =
|
||||
getChild<LLButton>("ok_button", recurse);
|
||||
getChild<LLButton>("invite_button", recurse);
|
||||
if ( mImplementation->mOKButton )
|
||||
{
|
||||
mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -39,11 +39,9 @@ class LLScrollListCtrl;
|
|||
class LLScrollListItem;
|
||||
class LLTextEditor;
|
||||
|
||||
// Forward declare for friend usage.
|
||||
//virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*);
|
||||
|
||||
typedef std::map<std::string,std::string> icon_map_t;
|
||||
|
||||
|
||||
class LLPanelGroupRoles : public LLPanelGroupTab
|
||||
{
|
||||
public:
|
||||
|
|
@ -92,6 +90,7 @@ protected:
|
|||
std::string mWantApplyMesg;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupSubTab : public LLPanelGroupTab
|
||||
{
|
||||
public:
|
||||
|
|
@ -143,10 +142,14 @@ protected:
|
|||
icon_map_t mActionIcons;
|
||||
|
||||
bool mActivated;
|
||||
|
||||
|
||||
bool mHasGroupBanPower; // Used to communicate between action sets due to the dependency between
|
||||
// GP_GROUP_BAN_ACCESS and GP_EJECT_MEMBER and GP_ROLE_REMOVE_MEMBER
|
||||
|
||||
void setOthersVisible(BOOL b);
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab
|
||||
{
|
||||
public:
|
||||
|
|
@ -173,6 +176,10 @@ public:
|
|||
void handleRoleCheck(const LLUUID& role_id,
|
||||
LLRoleMemberChangeType type);
|
||||
|
||||
static void onBanMember(void* user_data);
|
||||
void handleBanMember();
|
||||
|
||||
|
||||
void applyMemberChanges();
|
||||
bool addOwnerCB(const LLSD& notification, const LLSD& response);
|
||||
|
||||
|
|
@ -206,6 +213,7 @@ protected:
|
|||
LLScrollListCtrl* mAssignedRolesList;
|
||||
LLScrollListCtrl* mAllowedActionsList;
|
||||
LLButton* mEjectBtn;
|
||||
LLButton* mBanBtn;
|
||||
|
||||
BOOL mChanged;
|
||||
BOOL mPendingMemberUpdate;
|
||||
|
|
@ -219,6 +227,7 @@ protected:
|
|||
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
|
||||
{
|
||||
public:
|
||||
|
|
@ -241,7 +250,7 @@ public:
|
|||
|
||||
static void onActionCheck(LLUICtrl*, void*);
|
||||
bool addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check);
|
||||
|
||||
|
||||
static void onPropertiesKey(LLLineEditor*, void*);
|
||||
|
||||
void onDescriptionKeyStroke(LLTextEditor* caller);
|
||||
|
|
@ -260,6 +269,9 @@ public:
|
|||
void saveRoleChanges(bool select_saved_role);
|
||||
|
||||
virtual void setGroupID(const LLUUID& id);
|
||||
|
||||
BOOL mFirstOpen;
|
||||
|
||||
protected:
|
||||
void handleActionCheck(LLUICtrl* ctrl, bool force);
|
||||
LLSD createRoleItem(const LLUUID& role_id, std::string name, std::string title, S32 members);
|
||||
|
|
@ -281,6 +293,7 @@ protected:
|
|||
std::string mRemoveEveryoneTxt;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab
|
||||
{
|
||||
public:
|
||||
|
|
@ -308,4 +321,46 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class LLPanelGroupBanListSubTab : public LLPanelGroupSubTab
|
||||
{
|
||||
public:
|
||||
LLPanelGroupBanListSubTab();
|
||||
virtual ~LLPanelGroupBanListSubTab() {}
|
||||
|
||||
virtual BOOL postBuildSubTab(LLView* root);
|
||||
|
||||
virtual void activate();
|
||||
virtual void update(LLGroupChange gc);
|
||||
virtual void draw();
|
||||
|
||||
static void onBanEntrySelect(LLUICtrl* ctrl, void* user_data);
|
||||
void handleBanEntrySelect();
|
||||
|
||||
static void onCreateBanEntry(void* user_data);
|
||||
void handleCreateBanEntry();
|
||||
|
||||
static void onDeleteBanEntry(void* user_data);
|
||||
void handleDeleteBanEntry();
|
||||
|
||||
static void onRefreshBanList(void* user_data);
|
||||
void handleRefreshBanList();
|
||||
|
||||
void onBanListCompleted(bool isComplete);
|
||||
|
||||
protected:
|
||||
void setBanCount(U32 ban_count);
|
||||
void populateBanList();
|
||||
|
||||
public:
|
||||
virtual void setGroupID(const LLUUID& id);
|
||||
|
||||
protected:
|
||||
LLNameListCtrl* mBanList;
|
||||
LLButton* mCreateBanButton;
|
||||
LLButton* mDeleteBanButton;
|
||||
LLButton* mRefreshBanListButton;
|
||||
LLTextBase* mBanCountText;
|
||||
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELGROUPROLES_H
|
||||
|
|
|
|||
|
|
@ -488,8 +488,9 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
|
|||
gCacheName->getGroup(parcel->getGroupID(),
|
||||
boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionGroupText, _2));
|
||||
|
||||
gCacheName->getGroup(parcel->getGroupID(),
|
||||
boost::bind(&LLPanelPlaceInfo::onNameCache, mParcelOwner, _2));
|
||||
std::string owner =
|
||||
LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
|
||||
mParcelOwner->setText(owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2708,6 +2708,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||
capabilityNames.append("GetObjectCost");
|
||||
capabilityNames.append("GetObjectPhysicsData");
|
||||
capabilityNames.append("GetTexture");
|
||||
capabilityNames.append("GroupAPIv1");
|
||||
capabilityNames.append("GroupMemberData");
|
||||
capabilityNames.append("GroupProposalBallot");
|
||||
capabilityNames.append("HomeLocation");
|
||||
|
|
|
|||
|
|
@ -53,98 +53,100 @@ enum LLRoleChangeType
|
|||
|
||||
// KNOWN HOLES: use these for any single bit powers you need
|
||||
// bit 0x1 << 46
|
||||
// bit 0x1 << 49 and above
|
||||
// bit 0x1 << 52 and above
|
||||
|
||||
// These powers were removed to make group roles simpler
|
||||
// bit 0x1 << 41 (GP_ACCOUNTING_VIEW)
|
||||
// bit 0x1 << 46 (GP_PROPOSAL_VIEW)
|
||||
|
||||
const U64 GP_NO_POWERS = 0x0;
|
||||
const U64 GP_ALL_POWERS = 0xFFFFFFFFFFFFFFFFLL;
|
||||
const U64 GP_ALL_POWERS = 0xFFFFffffFFFFffffLL;
|
||||
|
||||
// Membership
|
||||
const U64 GP_MEMBER_INVITE = 0x1 << 1; // Invite member
|
||||
const U64 GP_MEMBER_EJECT = 0x1 << 2; // Eject member from group
|
||||
const U64 GP_MEMBER_OPTIONS = 0x1 << 3; // Toggle "Open enrollment" and change "Signup Fee"
|
||||
const U64 GP_MEMBER_VISIBLE_IN_DIR = 0x1LL << 47;
|
||||
const U64 GP_MEMBER_INVITE = 0x1LL << 1; // Invite member
|
||||
const U64 GP_MEMBER_EJECT = 0x1LL << 2; // Eject member from group
|
||||
const U64 GP_MEMBER_OPTIONS = 0x1LL << 3; // Toggle "Open enrollment" and change "Signup Fee"
|
||||
const U64 GP_MEMBER_VISIBLE_IN_DIR = 0x1LL << 47;
|
||||
|
||||
// Roles
|
||||
const U64 GP_ROLE_CREATE = 0x1 << 4; // Create new roles
|
||||
const U64 GP_ROLE_DELETE = 0x1 << 5; // Delete roles
|
||||
const U64 GP_ROLE_PROPERTIES = 0x1 << 6; // Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?)
|
||||
const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED = 0x1 << 7; // Assign Member to a Role that the assigner is in
|
||||
const U64 GP_ROLE_ASSIGN_MEMBER = 0x1 << 8; // Assign Member to Role
|
||||
const U64 GP_ROLE_REMOVE_MEMBER = 0x1 << 9; // Remove Member from Role
|
||||
const U64 GP_ROLE_CHANGE_ACTIONS = 0x1 << 10; // Change actions a role can perform
|
||||
const U64 GP_ROLE_CREATE = 0x1LL << 4; // Create new roles
|
||||
const U64 GP_ROLE_DELETE = 0x1LL << 5; // Delete roles
|
||||
const U64 GP_ROLE_PROPERTIES = 0x1LL << 6; // Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?)
|
||||
const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED = 0x1LL << 7; // Assign Member to a Role that the assigner is in
|
||||
const U64 GP_ROLE_ASSIGN_MEMBER = 0x1LL << 8; // Assign Member to Role
|
||||
const U64 GP_ROLE_REMOVE_MEMBER = 0x1LL << 9; // Remove Member from Role
|
||||
const U64 GP_ROLE_CHANGE_ACTIONS = 0x1LL << 10; // Change actions a role can perform
|
||||
|
||||
// Group Identity
|
||||
const U64 GP_GROUP_CHANGE_IDENTITY = 0x1 << 11; // Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes
|
||||
const U64 GP_GROUP_CHANGE_IDENTITY = 0x1LL << 11; // Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes
|
||||
|
||||
// Parcel Management
|
||||
const U64 GP_LAND_DEED = 0x1 << 12; // Deed Land and Buy Land for Group
|
||||
const U64 GP_LAND_RELEASE = 0x1 << 13; // Release Land (to Gov. Linden)
|
||||
const U64 GP_LAND_SET_SALE_INFO = 0x1 << 14; // Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land")
|
||||
const U64 GP_LAND_DIVIDE_JOIN = 0x1 << 15; // Divide and Join Parcels
|
||||
const U64 GP_LAND_DEED = 0x1LL << 12; // Deed Land and Buy Land for Group
|
||||
const U64 GP_LAND_RELEASE = 0x1LL << 13; // Release Land (to Gov. Linden)
|
||||
const U64 GP_LAND_SET_SALE_INFO = 0x1LL << 14; // Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land")
|
||||
const U64 GP_LAND_DIVIDE_JOIN = 0x1LL << 15; // Divide and Join Parcels
|
||||
|
||||
// Parcel Identity
|
||||
const U64 GP_LAND_FIND_PLACES = 0x1 << 17; // Toggle "Show in Find Places" and Set Category.
|
||||
const U64 GP_LAND_CHANGE_IDENTITY = 0x1 << 18; // Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox
|
||||
const U64 GP_LAND_SET_LANDING_POINT = 0x1 << 19; // Set Landing Point
|
||||
const U64 GP_LAND_FIND_PLACES = 0x1LL << 17; // Toggle "Show in Find Places" and Set Category.
|
||||
const U64 GP_LAND_CHANGE_IDENTITY = 0x1LL << 18; // Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox
|
||||
const U64 GP_LAND_SET_LANDING_POINT = 0x1LL << 19; // Set Landing Point
|
||||
|
||||
// Parcel Settings
|
||||
const U64 GP_LAND_CHANGE_MEDIA = 0x1 << 20; // Change Media Settings
|
||||
const U64 GP_LAND_EDIT = 0x1 << 21; // Toggle Edit Land
|
||||
const U64 GP_LAND_OPTIONS = 0x1 << 22; // Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes
|
||||
const U64 GP_LAND_CHANGE_MEDIA = 0x1LL << 20; // Change Media Settings
|
||||
const U64 GP_LAND_EDIT = 0x1LL << 21; // Toggle Edit Land
|
||||
const U64 GP_LAND_OPTIONS = 0x1LL << 22; // Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes
|
||||
|
||||
// Parcel Powers
|
||||
const U64 GP_LAND_ALLOW_EDIT_LAND = 0x1 << 23; // Bypass Edit Land Restriction
|
||||
const U64 GP_LAND_ALLOW_FLY = 0x1 << 24; // Bypass Fly Restriction
|
||||
const U64 GP_LAND_ALLOW_CREATE = 0x1 << 25; // Bypass Create/Edit Objects Restriction
|
||||
const U64 GP_LAND_ALLOW_LANDMARK = 0x1 << 26; // Bypass Landmark Restriction
|
||||
const U64 GP_LAND_ALLOW_SET_HOME = 0x1 << 28; // Bypass Set Home Point Restriction
|
||||
const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land
|
||||
|
||||
const U64 GP_LAND_ALLOW_EDIT_LAND = 0x1LL << 23; // Bypass Edit Land Restriction
|
||||
const U64 GP_LAND_ALLOW_FLY = 0x1LL << 24; // Bypass Fly Restriction
|
||||
const U64 GP_LAND_ALLOW_CREATE = 0x1LL << 25; // Bypass Create/Edit Objects Restriction
|
||||
const U64 GP_LAND_ALLOW_LANDMARK = 0x1LL << 26; // Bypass Landmark Restriction
|
||||
const U64 GP_LAND_ALLOW_SET_HOME = 0x1LL << 28; // Bypass Set Home Point Restriction
|
||||
const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land
|
||||
|
||||
// Parcel Access
|
||||
const U64 GP_LAND_MANAGE_ALLOWED = 0x1 << 29; // Manage Allowed List
|
||||
const U64 GP_LAND_MANAGE_BANNED = 0x1 << 30; // Manage Banned List
|
||||
const U64 GP_LAND_MANAGE_PASSES = 0x1LL << 31; // Change Sell Pass Settings
|
||||
const U64 GP_LAND_ADMIN = 0x1LL << 32; // Eject and Freeze Users on the land
|
||||
const U64 GP_LAND_MANAGE_ALLOWED = 0x1LL << 29; // Manage Allowed List
|
||||
const U64 GP_LAND_MANAGE_BANNED = 0x1LL << 30; // Manage Banned List
|
||||
const U64 GP_LAND_MANAGE_PASSES = 0x1LL << 31; // Change Sell Pass Settings
|
||||
const U64 GP_LAND_ADMIN = 0x1LL << 32; // Eject and Freeze Users on the land
|
||||
|
||||
// Parcel Content
|
||||
const U64 GP_LAND_RETURN_GROUP_SET = 0x1LL << 33; // Return objects on parcel that are set to group
|
||||
const U64 GP_LAND_RETURN_NON_GROUP = 0x1LL << 34; // Return objects on parcel that are not set to group
|
||||
const U64 GP_LAND_RETURN_GROUP_OWNED= 0x1LL << 48; // Return objects on parcel that are owned by the group
|
||||
const U64 GP_LAND_RETURN_GROUP_SET = 0x1LL << 33; // Return objects on parcel that are set to group
|
||||
const U64 GP_LAND_RETURN_NON_GROUP = 0x1LL << 34; // Return objects on parcel that are not set to group
|
||||
const U64 GP_LAND_RETURN_GROUP_OWNED = 0x1LL << 48; // Return objects on parcel that are owned by the group
|
||||
|
||||
// Select a power-bit based on an object's relationship to a parcel.
|
||||
const U64 GP_LAND_RETURN = GP_LAND_RETURN_GROUP_OWNED
|
||||
| GP_LAND_RETURN_GROUP_SET
|
||||
| GP_LAND_RETURN_NON_GROUP;
|
||||
|
||||
const U64 GP_LAND_GARDENING = 0x1LL << 35; // Parcel Gardening - plant and move linden trees
|
||||
const U64 GP_LAND_GARDENING = 0x1LL << 35; // Parcel Gardening - plant and move linden trees
|
||||
|
||||
// Object Management
|
||||
const U64 GP_OBJECT_DEED = 0x1LL << 36; // Deed Object
|
||||
const U64 GP_OBJECT_MANIPULATE = 0x1LL << 38; // Manipulate Group Owned Objects (Move, Copy, Mod)
|
||||
const U64 GP_OBJECT_SET_SALE = 0x1LL << 39; // Set Group Owned Object for Sale
|
||||
const U64 GP_OBJECT_DEED = 0x1LL << 36; // Deed Object
|
||||
const U64 GP_OBJECT_MANIPULATE = 0x1LL << 38; // Manipulate Group Owned Objects (Move, Copy, Mod)
|
||||
const U64 GP_OBJECT_SET_SALE = 0x1LL << 39; // Set Group Owned Object for Sale
|
||||
|
||||
// Accounting
|
||||
const U64 GP_ACCOUNTING_ACCOUNTABLE = 0x1LL << 40; // Pay Group Liabilities and Receive Group Dividends
|
||||
const U64 GP_ACCOUNTING_ACCOUNTABLE = 0x1LL << 40; // Pay Group Liabilities and Receive Group Dividends
|
||||
|
||||
// Notices
|
||||
const U64 GP_NOTICES_SEND = 0x1LL << 42; // Send Notices
|
||||
const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice History
|
||||
const U64 GP_NOTICES_SEND = 0x1LL << 42; // Send Notices
|
||||
const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice History
|
||||
|
||||
// Proposals
|
||||
// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856:
|
||||
const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal
|
||||
const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal
|
||||
// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856:
|
||||
const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal
|
||||
const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal
|
||||
|
||||
// Group chat moderation related
|
||||
const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session
|
||||
const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk
|
||||
const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session
|
||||
const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session
|
||||
const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk
|
||||
const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session
|
||||
|
||||
// Group Banning
|
||||
const U64 GP_GROUP_BAN_ACCESS = 0x1LL << 51; // Allows access to ban / un-ban agents from a group.
|
||||
|
||||
const U64 GP_DEFAULT_MEMBER = GP_ACCOUNTING_ACCOUNTABLE
|
||||
| GP_LAND_ALLOW_SET_HOME
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ Second Life is brought to you by the Lindens:
|
|||
top_pad="10"
|
||||
width="435"
|
||||
word_wrap="true">
|
||||
Philip, Andrew, Doug, Richard, Phoenix, Ian, Mark, Robin, Dan, Char, Ryan, Eric, Jim, Lee, Jeff, Michael, Kelly, Steve, Catherine, Bub, Ramzi, Jill, Jeska, Don, Kona, Callum, Charity, Jack, Shawn, babbage, James, Lauren, Blue, Brent, Reuben, Pathfinder, Jesse, Patsy, Torley, Bo, Cyn, Jonathan, Gia, Annette, Ginsu, Harry, Lex, Runitai, Guy, Cornelius, Beth, Swiss, Thumper, Wendy, Teeple, Seth, Dee, Mia, Sally, Liana, Aura, Beez, Milo, Red, Gulliver, Marius, Joe, Jose, Dore, Justin, Nora, Morpheus, Lexie, Amber, Chris, Xan, Leyla, Walker, Sabin, Joshua, Hiromi, Tofu, Fritz, June, Jean, Ivy, Dez, Ken, Betsy, Which, Spike, Rob, Zee, Dustin, George, Claudia, del, Matthew, jane, jay, Adrian, Yool, Rika, Yoz, siobhan, Qarl, Benjamin, Beast, Everett, madhavi, Christopher, Izzy, stephany, Jeremy, sean, adreanne, Pramod, Tobin, sejong, Iridium, maurice, kj, Meta, kari, JP, bert, kyle, Jon, Socrates, Bridie, Ivan, maria, Aric, Coco, Periapse, sandy, Storrs, Lotte, Colossus, Brad, Pastrami, Zen, BigPapi, Banzai, Sardonyx, Mani, Garry, Jaime, Neuro, Samuel, Niko, CeeLo, Austin, Soft, Poppy, emma, tessa, angelo, kurz, alexa, Sue, CG, Blake, Erica, Brett, Bevis, kristen, Q, simon, Enus, MJ, laurap, Kip, Scouse, Ron, Ram, kend, Marty, Prospero, melissa, kraft, Nat, Seraph, Hamilton, Lordan, Green, miz, Ashlei, Trinity, Ekim, Echo, Charlie, Rowan, Rome, Jt, Doris, benoc, Christy, Bao, Kate, Tj, Patch, Cheah, Johan, Brandy, Angela, Oreh, Cogsworth, Lan, Mitchell, Space, Bambers, Einstein, Bender, Malbers, Matias, Maggie, Rothman, Milton, Niall, Marin, Allison, Mango, Andrea, Katt, Yi, Ambroff, Rico, Raymond, Gail, Christa, William, Dawn, Usi, Dynamike, M, Corr, Dante, Molly, kaylee, Danica, Kelv, Lil, jacob, Nya, Rodney, elsie, Blondin, Grant, Nyx, Devin, Monty, Minerva, Keira, Katie, Jenn, Makai, Clare, Joy, Cody, Gayathri, FJ, spider, Oskar, Landon, Jarv, Noelle, Al, Doc, Gray, Vir, t, Maestro, Simone, Shannon, yang, Courtney, Scott, charlene, Quixote, Susan, Zed, Amanda, Katelin, Esbee, JoRoan, Enkidu, roxie, Scarlet, Merov, Kevin, Judy, Rand, Newell, Les, Dessie, Galen, Michon, Geo, Siz, Calyle, Pete, Praveen, Callen, Sheldon, Pink, Nelson, jenelle, Terrence, Nathan, Juan, Sascha, Huseby, Karina, Kaye, Kotler, Lis, Darv, Charrell, Dakota, Kimmora, Theeba, Taka, Mae, Perry, Ducot, dana, Esther, Dough, gisele, Doten, Viale, Fisher, jessieann, ashley, Torres, delby, rountree, kurt, Slaton, Madison, Rue, Gino, Wen, Casssandra, Brodesky, Squid, Gez, Rakesh, Gecko, Ladan, Tony, Tatem, Squire, Falcon, BK, Crimp, Tiggs, Bacon, Coyot, Carmilla, Webb, Sea, Arch, Jillian, Jason, Bernard, Vogt, Peggy, dragon, Pup, xandix, Wallace, Bewest, Inoshiro, Rhett, AG, Aimee, Ghengis, Itiaes, Eli, Steffan, Epic, Grapes, Stone, Prep, Scobu, Robert, Alain, Carla, Vicky, Tia, Alec, Taras, Lisa, Oz, Ariane, Log, House, Kazu, Kim, Drofnas, Tyler, Campbell, Michele, Madeline, Nelly, Baron, Thor, Lori, Hele, Fredrik, Teddy, Pixie, Berry, Gabrielle, Alfonso, Brooke, Wolf, Ringo, Cru, Charlar, Rodvik, Gibson, Elise, Bagman, Greger, Leonidas, Jerm, Leslie, CB, Brenda, Durian, Carlo, mm, Zeeshan, Caleb, Max, Elikak, Mercille, Steph, Chase
|
||||
Philip, Andrew, Doug, Richard, Phoenix, Ian, Mark, Robin, Dan, Char, Ryan, Eric, Jim, Lee, Jeff, Michael, Kelly, Steve, Catherine, Bub, Ramzi, Jill, Jeska, Don, Kona, Callum, Charity, Jack, Shawn, babbage, James, Lauren, Blue, Brent, Reuben, Pathfinder, Jesse, Patsy, Torley, Bo, Cyn, Jonathan, Gia, Annette, Ginsu, Harry, Lex, Runitai, Guy, Cornelius, Beth, Swiss, Thumper, Wendy, Teeple, Seth, Dee, Mia, Sally, Liana, Aura, Beez, Milo, Red, Gulliver, Marius, Joe, Jose, Dore, Justin, Nora, Morpheus, Lexie, Amber, Chris, Xan, Leyla, Walker, Sabin, Joshua, Hiromi, Tofu, Fritz, June, Jean, Ivy, Dez, Ken, Betsy, Which, Spike, Rob, Zee, Dustin, George, Claudia, del, Matthew, jane, jay, Adrian, Yool, Rika, Yoz, siobhan, Qarl, Benjamin, Beast, Everett, madhavi, Christopher, Izzy, stephany, Jeremy, sean, adreanne, Pramod, Tobin, sejong, Iridium, maurice, kj, Meta, kari, JP, bert, kyle, Jon, Socrates, Bridie, Ivan, maria, Aric, Coco, Periapse, sandy, Storrs, Lotte, Colossus, Brad, Pastrami, Zen, BigPapi, Banzai, Sardonyx, Mani, Garry, Jaime, Neuro, Samuel, Niko, CeeLo, Austin, Soft, Poppy, emma, tessa, angelo, kurz, alexa, Sue, CG, Blake, Erica, Brett, Bevis, kristen, Q, simon, Enus, MJ, laurap, Kip, Scouse, Ron, Ram, kend, Marty, Prospero, melissa, kraft, Nat, Seraph, Hamilton, Lordan, Green, miz, Ashlei, Trinity, Ekim, Echo, Charlie, Rowan, Rome, Jt, Doris, benoc, Christy, Bao, Kate, Tj, Patch, Cheah, Johan, Brandy, Angela, Oreh, Cogsworth, Lan, Mitchell, Space, Bambers, Einstein, Bender, Malbers, Matias, Maggie, Rothman, Milton, Niall, Marin, Allison, Mango, Andrea, Katt, Yi, Ambroff, Rico, Raymond, Gail, Christa, William, Dawn, Usi, Dynamike, M, Corr, Dante, Molly, kaylee, Danica, Kelv, Lil, jacob, Nya, Rodney, elsie, Blondin, Grant, Nyx, Devin, Monty, Minerva, Keira, Katie, Jenn, Makai, Clare, Joy, Cody, Gayathri, FJ, spider, Oskar, Landon, Jarv, Noelle, Al, Doc, Gray, Vir, t, Maestro, Simone, Shannon, yang, Courtney, Scott, charlene, Quixote, Susan, Zed, Amanda, Katelin, Esbee, JoRoan, Enkidu, roxie, Scarlet, Merov, Kevin, Judy, Rand, Newell, Les, Dessie, Galen, Michon, Geo, Siz, Calyle, Pete, Praveen, Callen, Sheldon, Pink, Nelson, jenelle, Terrence, Nathan, Juan, Sascha, Huseby, Karina, Kaye, Kotler, Lis, Darv, Charrell, Dakota, Kimmora, Theeba, Taka, Mae, Perry, Ducot, dana, Esther, Dough, gisele, Doten, Viale, Fisher, jessieann, ashley, Torres, delby, rountree, kurt, Slaton, Madison, Rue, Gino, Wen, Casssandra, Brodesky, Squid, Gez, Rakesh, Gecko, Ladan, Tony, Tatem, Squire, Falcon, BK, Crimp, Tiggs, Bacon, Coyot, Carmilla, Webb, Sea, Arch, Jillian, Jason, Bernard, Vogt, Peggy, dragon, Pup, xandix, Wallace, Bewest, Inoshiro, Rhett, AG, Aimee, Ghengis, Itiaes, Eli, Steffan, Epic, Grapes, Stone, Prep, Scobu, Robert, Alain, Carla, Vicky, Tia, Alec, Taras, Lisa, Oz, Ariane, Log, House, Kazu, Kim, Drofnas, Tyler, Campbell, Michele, Madeline, Nelly, Baron, Thor, Lori, Hele, Fredrik, Teddy, Pixie, Berry, Gabrielle, Alfonso, Brooke, Wolf, Ringo, Cru, Charlar, Rodvik, Gibson, Elise, Bagman, Greger, Leonidas, Jerm, Leslie, CB, Brenda, Durian, Carlo, mm, Zeeshan, Caleb, Max, Elikak, Mercille, Steph, Chase, Baker
|
||||
</text_editor>
|
||||
<text
|
||||
follows="top|left"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
layout="topleft"
|
||||
name="open_voice_conversation">
|
||||
<on_click function="Avatar.DoToSelected" parameter="open_voice_conversation"/>
|
||||
<on_enable function="Avatar.EnableItem" parameter="can_open_voice_conversation"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Disconnect from voice"
|
||||
|
|
@ -213,4 +214,12 @@
|
|||
<on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
|
||||
</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="Avatar.DoToSelected" parameter="ban_member" />
|
||||
<on_enable function="Avatar.EnableItem" parameter="can_ban_member" />
|
||||
</menu_item_call>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -506,7 +506,35 @@ Add this Ability to '[ROLE_NAME]'?
|
|||
notext="No"
|
||||
yestext="Yes"/>
|
||||
</notification>
|
||||
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="AssignBanAbilityWarning"
|
||||
type="alertmodal">
|
||||
You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'.
|
||||
|
||||
*WARNING*
|
||||
Any Member in a Role with this Ability will also be granted the Abilities '[ACTION_NAME_2]' and '[ACTION_NAME_3]'
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="RemoveBanAbilityWarning"
|
||||
type="alertmodal">
|
||||
You are removing the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'.
|
||||
|
||||
*WARNING*
|
||||
Removing this ability will NOT remove the Abilities '[ACTION_NAME_2]' and '[ACTION_NAME_3]'.
|
||||
|
||||
If you no longer wish to have these abilities granted to this role, disable them immediately!
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="EjectGroupMemberWarning"
|
||||
|
|
@ -3746,6 +3774,28 @@ Leave Group?
|
|||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="aler.tga"
|
||||
name="GroupDepartError"
|
||||
type="alert">
|
||||
Unable to leave group: [reason].
|
||||
<tag>reason</tag>
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alert.tga"
|
||||
name="GroupDepart"
|
||||
type="alert">
|
||||
You have left the group [group_name].
|
||||
<tag>group_name</tag>
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alert.tga"
|
||||
name="ConfirmKick"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="330"
|
||||
label="Ban Residents"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="bulk_ban_panel"
|
||||
top="330"
|
||||
width="210">
|
||||
<panel.string
|
||||
name="loading">
|
||||
(loading...)
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="ban_selection_too_large">
|
||||
Group bans not sent: too many Residents selected. Group bans are limited to 100 per request.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="ban_not_permitted">
|
||||
Group ban not sent: you do not have 'Manage ban list' ability.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="ban_limit_fail">
|
||||
Group ban not sent: your group have reached limit of allowed ban records.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="partial_ban">
|
||||
Some group bans were not sent:
|
||||
[REASONS]
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="ban_failed">
|
||||
Group bans were not sent:
|
||||
[REASONS]
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="residents_already_banned">
|
||||
- The following resident(s) are already banned: [RESIDENTS].
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="ban_limit_reached">
|
||||
- Ban limit reached, following agents not banned: [RESIDENTS].
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="cant_ban_yourself">
|
||||
- You cannot ban yourself from a group.
|
||||
</panel.string>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
height="54"
|
||||
layout="topleft"
|
||||
left="7"
|
||||
name="help_text"
|
||||
top="28"
|
||||
word_wrap="true"
|
||||
width="200">
|
||||
You can select multiple Residents to ban from your group. Click 'Open Resident Chooser' to start.
|
||||
</text>
|
||||
<button
|
||||
height="20"
|
||||
label="Open Resident Chooser"
|
||||
layout="topleft"
|
||||
left_delta="-2"
|
||||
name="add_button"
|
||||
top_delta="44"
|
||||
width="200" />
|
||||
<name_list
|
||||
allow_calling_card_drop="true"
|
||||
column_padding="0"
|
||||
height="174"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
multi_select="true"
|
||||
name="banned_agent_list"
|
||||
tool_tip="Hold the Ctrl key and click Resident names to multi-select"
|
||||
top_pad="4"
|
||||
width="200" />
|
||||
<button
|
||||
height="20"
|
||||
label="Remove Selected from List"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="remove_button"
|
||||
tool_tip="Removes the Residents selected above from the ban list"
|
||||
top_pad="4"
|
||||
width="200" />
|
||||
<button
|
||||
height="20"
|
||||
label="Ban Residents"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="ban_button"
|
||||
top_delta="30"
|
||||
width="135" />
|
||||
<button
|
||||
height="20"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
left_pad="2"
|
||||
name="cancel_button"
|
||||
top_delta="0"
|
||||
width="65" />
|
||||
<string
|
||||
name="GroupBulkBan">
|
||||
Group Ban
|
||||
</string>
|
||||
</panel>
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
Choose what Role to assign them to:
|
||||
</text>
|
||||
<combo_box
|
||||
height="16"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="role_name"
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
label="Send Invitations"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="ok_button"
|
||||
name="invite_button"
|
||||
top="356"
|
||||
width="135" />
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -118,6 +118,13 @@ clicking on their names.
|
|||
left_pad="10"
|
||||
name="member_eject"
|
||||
width="100" />
|
||||
<button
|
||||
height="23"
|
||||
label="Ban Member(s)"
|
||||
follows="top|left"
|
||||
left_pad="10"
|
||||
name="member_ban"
|
||||
width="100" />
|
||||
</panel>
|
||||
<panel
|
||||
border="false"
|
||||
|
|
@ -138,291 +145,372 @@ clicking on their names.
|
|||
right="-5"
|
||||
name="show_all_button"
|
||||
width="100" />-->
|
||||
<panel.string
|
||||
name="help_text">
|
||||
Roles have a title and an allowed list of Abilities
|
||||
that Members can perform. Members can belong to
|
||||
one or more Roles. A group can have up to 10 Roles,
|
||||
including the Everyone and Owner Roles.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="cant_delete_role">
|
||||
The 'Everyone' and 'Owners' Roles are special and can't be deleted.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_folder_icon" translate="false">
|
||||
Inv_FolderClosed
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_all_have_icon" translate="false">
|
||||
Checkbox_On
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_partial_icon" translate="false">
|
||||
Checkbox_Off
|
||||
</panel.string>
|
||||
<filter_editor
|
||||
layout="topleft"
|
||||
top="5"
|
||||
left="5"
|
||||
right="-5"
|
||||
height="22"
|
||||
search_button_visible="false"
|
||||
follows="left|top|right"
|
||||
label="Filter Roles"
|
||||
name="filter_input" />
|
||||
<scroll_list
|
||||
column_padding="0"
|
||||
draw_heading="true"
|
||||
draw_stripes="false"
|
||||
heading_height="23"
|
||||
height="132"
|
||||
layout="topleft"
|
||||
search_column="1"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
name="role_list"
|
||||
top_pad="2"
|
||||
width="310">
|
||||
<scroll_list.columns
|
||||
label="Role"
|
||||
name="name"
|
||||
relative_width="0.45" />
|
||||
<scroll_list.columns
|
||||
label="Title"
|
||||
name="title"
|
||||
relative_width="0.45" />
|
||||
<scroll_list.columns
|
||||
label="#"
|
||||
name="members"
|
||||
relative_width="0.15" />
|
||||
</scroll_list>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
label="New Role"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="role_create"
|
||||
width="120" />
|
||||
<button
|
||||
height="23"
|
||||
follows="top|left"
|
||||
label="Delete Role"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
name="role_delete"
|
||||
width="120" />
|
||||
</panel>
|
||||
<panel
|
||||
border="false"
|
||||
height="303"
|
||||
label="ABILITIES"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
help_topic="roles_actions_tab"
|
||||
name="actions_sub_tab"
|
||||
class="panel_group_actions_subtab"
|
||||
tool_tip="You can view an Ability's Description and which Roles and Members can execute the Ability."
|
||||
width="310">
|
||||
<panel.string
|
||||
name="help_text">
|
||||
Abilities allow Members in Roles to do specific
|
||||
things in this group. There's a broad variety of Abilities.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_folder_icon" translate="false">
|
||||
Inv_FolderClosed
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_all_have_icon" translate="false">
|
||||
Checkbox_On
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_partial_icon" translate="false">
|
||||
Checkbox_Off
|
||||
</panel.string>
|
||||
<filter_editor
|
||||
layout="topleft"
|
||||
top="5"
|
||||
left="5"
|
||||
right="-5"
|
||||
height="22"
|
||||
search_button_visible="false"
|
||||
follows="left|top|right"
|
||||
label="Filter Abilities"
|
||||
name="filter_input" />
|
||||
<scroll_list
|
||||
column_padding="0"
|
||||
draw_stripes="true"
|
||||
height="200"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
name="action_list"
|
||||
search_column="2"
|
||||
tool_tip="Select an Ability to view more details"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="icon"
|
||||
width="2" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="action"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
</panel>
|
||||
</tab_container>
|
||||
<panel
|
||||
height="350"
|
||||
background_visible="false"
|
||||
bg_alpha_color="FloaterUnfocusBorderColor"
|
||||
layout="topleft"
|
||||
follows="top|left|right"
|
||||
left="0"
|
||||
right="-1"
|
||||
width="313"
|
||||
mouse_opaque="false"
|
||||
name="members_footer"
|
||||
top="325"
|
||||
visible="false">
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
top="8"
|
||||
text_color="EmphasisColor"
|
||||
name="static"
|
||||
width="300">
|
||||
Assigned Roles
|
||||
</text>
|
||||
<scroll_list
|
||||
draw_stripes="true"
|
||||
follows="left|top|right"
|
||||
height="150"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
name="member_assigned_roles"
|
||||
top_pad="0">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="role"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
top_pad="5"
|
||||
text_color="EmphasisColor"
|
||||
name="static2"
|
||||
width="285">
|
||||
Allowed Abilities
|
||||
</text>
|
||||
<scroll_list
|
||||
draw_stripes="true"
|
||||
follows="left|top|right"
|
||||
height="150"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
name="member_allowed_actions"
|
||||
search_column="2"
|
||||
tool_tip="For details of each allowed ability see the abilities tab"
|
||||
top_pad="0">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="icon"
|
||||
width="2" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="action"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
<panel.string
|
||||
name="help_text">
|
||||
Roles have a title and an allowed list of Abilities
|
||||
that Members can perform. Members can belong to
|
||||
one or more Roles. A group can have up to 10 Roles,
|
||||
including the Everyone and Owner Roles.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="cant_delete_role">
|
||||
The 'Everyone' and 'Owners' Roles are special and can't be deleted.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_folder_icon" translate="false">
|
||||
Inv_FolderClosed
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_all_have_icon" translate="false">
|
||||
Checkbox_On
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_partial_icon" translate="false">
|
||||
Checkbox_Off
|
||||
</panel.string>
|
||||
<filter_editor
|
||||
layout="topleft"
|
||||
top="5"
|
||||
left="5"
|
||||
right="-5"
|
||||
height="22"
|
||||
search_button_visible="false"
|
||||
follows="left|top|right"
|
||||
label="Filter Roles"
|
||||
name="filter_input" />
|
||||
<scroll_list
|
||||
column_padding="0"
|
||||
draw_heading="true"
|
||||
draw_stripes="false"
|
||||
heading_height="23"
|
||||
height="132"
|
||||
layout="topleft"
|
||||
search_column="1"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
name="role_list"
|
||||
top_pad="2"
|
||||
width="310">
|
||||
<scroll_list.columns
|
||||
label="Role"
|
||||
name="name"
|
||||
relative_width="0.45" />
|
||||
<scroll_list.columns
|
||||
label="Title"
|
||||
name="title"
|
||||
relative_width="0.45" />
|
||||
<scroll_list.columns
|
||||
label="#"
|
||||
name="members"
|
||||
relative_width="0.15" />
|
||||
</scroll_list>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
label="New Role"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="role_create"
|
||||
width="120" />
|
||||
<button
|
||||
height="23"
|
||||
follows="top|left"
|
||||
label="Delete Role"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
name="role_delete"
|
||||
width="120" />
|
||||
</panel>
|
||||
<panel
|
||||
height="550"
|
||||
background_visible="false"
|
||||
bg_alpha_color="FloaterUnfocusBorderColor"
|
||||
border="false"
|
||||
height="303"
|
||||
label="ABILITIES"
|
||||
layout="topleft"
|
||||
follows="top|left|right"
|
||||
left="0"
|
||||
right="-1"
|
||||
width="313"
|
||||
mouse_opaque="false"
|
||||
name="roles_footer"
|
||||
top_delta="0"
|
||||
top="209"
|
||||
visible="false">
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
top="5"
|
||||
name="static"
|
||||
width="300">
|
||||
Role Name
|
||||
</text>
|
||||
<line_editor
|
||||
type="string"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
help_topic="roles_actions_tab"
|
||||
name="actions_sub_tab"
|
||||
class="panel_group_actions_subtab"
|
||||
tool_tip="You can view an Ability's Description and which Roles and Members can execute the Ability."
|
||||
width="310">
|
||||
<panel.string
|
||||
name="help_text">
|
||||
Abilities allow Members in Roles to do specific
|
||||
things in this group. There's a broad variety of Abilities.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_folder_icon" translate="false">
|
||||
Inv_FolderClosed
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_all_have_icon" translate="false">
|
||||
Checkbox_On
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="power_partial_icon" translate="false">
|
||||
Checkbox_Off
|
||||
</panel.string>
|
||||
<filter_editor
|
||||
layout="topleft"
|
||||
top="5"
|
||||
left="5"
|
||||
right="-5"
|
||||
height="22"
|
||||
search_button_visible="false"
|
||||
follows="left|top|right"
|
||||
label="Filter Abilities"
|
||||
name="filter_input" />
|
||||
<scroll_list
|
||||
column_padding="0"
|
||||
draw_stripes="true"
|
||||
height="200"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
name="action_list"
|
||||
search_column="2"
|
||||
tool_tip="Select an Ability to view more details"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="icon"
|
||||
width="2" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="action"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel
|
||||
border="false"
|
||||
height="303"
|
||||
label="BANNED RESIDENTS"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
help_topic="roles_banlist_tab"
|
||||
name="banlist_sub_tab"
|
||||
class="panel_group_banlist_subtab"
|
||||
tool_tip="View the banned residents from this group."
|
||||
width="310">
|
||||
<panel.string
|
||||
name="help_text">
|
||||
Any resident on the ban list will be unable to join the group.
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="ban_count_template">
|
||||
Ban count: [COUNT]/[LIMIT]
|
||||
</panel.string>
|
||||
<name_list
|
||||
column_padding="0"
|
||||
draw_heading="true"
|
||||
height="400"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
multi_select="true"
|
||||
name="ban_list"
|
||||
short_names="false"
|
||||
top_pad="5">
|
||||
<name_list.columns
|
||||
label="Resident"
|
||||
name="name"
|
||||
font.name="SANSSERIF_SMALL"
|
||||
font.style="NORMAL"
|
||||
relative_width="0.7" />
|
||||
<name_list.columns
|
||||
label="Date Banned"
|
||||
name="ban_date"
|
||||
relative_width="0.3" />
|
||||
</name_list>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
label="Ban Resident(s)"
|
||||
layout="topleft"
|
||||
left="3"
|
||||
name="ban_create"
|
||||
tool_tip="Ban residents from your group"
|
||||
width="120" />
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
label="Remove Ban(s)"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
name="ban_delete"
|
||||
tool_tip="Unban selected residents from your group"
|
||||
width="120" />
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
width="23"
|
||||
image_overlay="Refresh_Off"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
name="ban_refresh"
|
||||
tool_tip="Refresh the ban list"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
height="18"
|
||||
left_pad="5"
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
name="ban_count"
|
||||
width="100">
|
||||
</text>
|
||||
</panel>
|
||||
</tab_container>
|
||||
<panel
|
||||
height="350"
|
||||
background_visible="false"
|
||||
bg_alpha_color="FloaterUnfocusBorderColor"
|
||||
layout="topleft"
|
||||
follows="top|left|right"
|
||||
left="0"
|
||||
right="-1"
|
||||
width="313"
|
||||
mouse_opaque="false"
|
||||
name="members_footer"
|
||||
top="325"
|
||||
visible="false">
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
top="8"
|
||||
text_color="EmphasisColor"
|
||||
name="static"
|
||||
width="300">
|
||||
Assigned Roles
|
||||
</text>
|
||||
<scroll_list
|
||||
draw_stripes="true"
|
||||
follows="left|top|right"
|
||||
height="150"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
name="member_assigned_roles"
|
||||
top_pad="0">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="role"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
top_pad="5"
|
||||
text_color="EmphasisColor"
|
||||
name="static2"
|
||||
width="285">
|
||||
Allowed Abilities
|
||||
</text>
|
||||
<scroll_list
|
||||
draw_stripes="true"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
max_length_bytes="20"
|
||||
name="role_name"
|
||||
top_pad="0"
|
||||
width="300">
|
||||
</line_editor>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
name="static3"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
Role Title
|
||||
</text>
|
||||
<line_editor
|
||||
type="string"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
max_length_bytes="20"
|
||||
name="role_title"
|
||||
top_pad="0"
|
||||
width="300">
|
||||
</line_editor>
|
||||
<text
|
||||
height="150"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
name="member_allowed_actions"
|
||||
search_column="2"
|
||||
tool_tip="For details of each allowed ability see the abilities tab"
|
||||
top_pad="0">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="icon"
|
||||
width="2" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="action"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel
|
||||
height="550"
|
||||
background_visible="false"
|
||||
bg_alpha_color="FloaterUnfocusBorderColor"
|
||||
layout="topleft"
|
||||
follows="top|left|right"
|
||||
left="0"
|
||||
right="-1"
|
||||
width="313"
|
||||
mouse_opaque="false"
|
||||
name="roles_footer"
|
||||
top_delta="0"
|
||||
top="209"
|
||||
visible="false">
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
top="5"
|
||||
name="static"
|
||||
width="300">
|
||||
Role Name
|
||||
</text>
|
||||
<line_editor
|
||||
type="string"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
max_length_bytes="20"
|
||||
name="role_name"
|
||||
top_pad="0"
|
||||
width="300">
|
||||
</line_editor>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
name="static3"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
Role Title
|
||||
</text>
|
||||
<line_editor
|
||||
type="string"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
max_length_bytes="20"
|
||||
name="role_title"
|
||||
top_pad="0"
|
||||
width="300">
|
||||
</line_editor>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
|
|
@ -431,161 +519,161 @@ things in this group. There's a broad variety of Abilities.
|
|||
name="static2"
|
||||
top_pad="5"
|
||||
width="200">
|
||||
Description
|
||||
</text>
|
||||
<text_editor
|
||||
type="string"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
max_length="295"
|
||||
height="35"
|
||||
name="role_description"
|
||||
top_pad="0"
|
||||
width="300"
|
||||
word_wrap="true">
|
||||
</text_editor>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
text_color="EmphasisColor"
|
||||
name="static4"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
Assigned Members
|
||||
</text>
|
||||
<name_list
|
||||
draw_stripes="true"
|
||||
height="128"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
name="role_assigned_members"
|
||||
top_pad="0"
|
||||
width="300" />
|
||||
<check_box
|
||||
height="15"
|
||||
label="Reveal members"
|
||||
left="5"
|
||||
layout="topleft"
|
||||
name="role_visible_in_list"
|
||||
tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."
|
||||
top_pad="4"
|
||||
width="300" />
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
text_color="EmphasisColor"
|
||||
name="static5"
|
||||
top_pad="2"
|
||||
width="300">
|
||||
Allowed Abilities
|
||||
</text>
|
||||
<scroll_list
|
||||
draw_stripes="true"
|
||||
height="140"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
name="role_allowed_actions"
|
||||
search_column="2"
|
||||
tool_tip="For details of each allowed ability see the abilities tab"
|
||||
top_pad="0"
|
||||
width="300">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="icon"
|
||||
width="2" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="action"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel
|
||||
height="424"
|
||||
background_visible="false"
|
||||
bg_alpha_color="FloaterUnfocusBorderColor"
|
||||
Description
|
||||
</text>
|
||||
<text_editor
|
||||
type="string"
|
||||
layout="topleft"
|
||||
follows="top|left|right"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
max_length="295"
|
||||
height="35"
|
||||
name="role_description"
|
||||
top_pad="0"
|
||||
width="300"
|
||||
word_wrap="true">
|
||||
</text_editor>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
text_color="EmphasisColor"
|
||||
name="static4"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
Assigned Members
|
||||
</text>
|
||||
<name_list
|
||||
draw_stripes="true"
|
||||
height="128"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
name="role_assigned_members"
|
||||
top_pad="0"
|
||||
width="300" />
|
||||
<check_box
|
||||
height="15"
|
||||
label="Reveal members"
|
||||
left="5"
|
||||
layout="topleft"
|
||||
name="role_visible_in_list"
|
||||
tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."
|
||||
top_pad="4"
|
||||
width="300" />
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
text_color="EmphasisColor"
|
||||
name="static5"
|
||||
top_pad="2"
|
||||
width="300">
|
||||
Allowed Abilities
|
||||
</text>
|
||||
<scroll_list
|
||||
draw_stripes="true"
|
||||
height="140"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
follows="left|top|right"
|
||||
right="-1"
|
||||
name="role_allowed_actions"
|
||||
search_column="2"
|
||||
tool_tip="For details of each allowed ability see the abilities tab"
|
||||
top_pad="0"
|
||||
width="300">
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="icon"
|
||||
width="2" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="checkbox"
|
||||
width="20" />
|
||||
<scroll_list.columns
|
||||
label=""
|
||||
name="action"
|
||||
width="270" />
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel
|
||||
height="424"
|
||||
background_visible="false"
|
||||
bg_alpha_color="FloaterUnfocusBorderColor"
|
||||
layout="topleft"
|
||||
follows="top|left|right"
|
||||
left="0"
|
||||
right="-1"
|
||||
width="313"
|
||||
mouse_opaque="false"
|
||||
name="actions_footer"
|
||||
top_delta="0"
|
||||
top="255"
|
||||
visible="false">
|
||||
<text_editor
|
||||
bg_readonly_color="Transparent"
|
||||
text_readonly_color="EmphasisColor"
|
||||
font="SansSerifSmall"
|
||||
type="string"
|
||||
enabled="false"
|
||||
halign="left"
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
left="0"
|
||||
right="-1"
|
||||
width="313"
|
||||
mouse_opaque="false"
|
||||
name="actions_footer"
|
||||
top_delta="0"
|
||||
top="255"
|
||||
visible="false">
|
||||
<text_editor
|
||||
bg_readonly_color="Transparent"
|
||||
text_readonly_color="EmphasisColor"
|
||||
font="SansSerifSmall"
|
||||
type="string"
|
||||
enabled="false"
|
||||
halign="left"
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
left="0"
|
||||
right="-1"
|
||||
height="90"
|
||||
max_length="512"
|
||||
name="action_description"
|
||||
top="0"
|
||||
word_wrap="true">
|
||||
This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner.
|
||||
</text_editor>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
name="static2"
|
||||
top_pad="1"
|
||||
width="300">
|
||||
Roles with this ability
|
||||
</text>
|
||||
<scroll_list
|
||||
height="172"
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
left="5"
|
||||
right="-1"
|
||||
name="action_roles"
|
||||
top_pad="0"
|
||||
width="300" />
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
name="static3"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
Members with this ability
|
||||
</text>
|
||||
<name_list
|
||||
height="122"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
right="-1"
|
||||
name="action_members"
|
||||
top_pad="0"
|
||||
width="300" />
|
||||
</panel>
|
||||
height="90"
|
||||
max_length="512"
|
||||
name="action_description"
|
||||
top="0"
|
||||
word_wrap="true">
|
||||
This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner.
|
||||
</text_editor>
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
name="static2"
|
||||
top_pad="1"
|
||||
width="300">
|
||||
Roles with this ability
|
||||
</text>
|
||||
<scroll_list
|
||||
height="172"
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
left="5"
|
||||
right="-1"
|
||||
name="action_roles"
|
||||
top_pad="0"
|
||||
width="300" />
|
||||
<text
|
||||
type="string"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
name="static3"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
Members with this ability
|
||||
</text>
|
||||
<name_list
|
||||
height="122"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
right="-1"
|
||||
name="action_members"
|
||||
top_pad="0"
|
||||
width="300" />
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@
|
|||
<action description="Eject Members from this Group"
|
||||
longdescription="Eject Members from this Group using the 'Eject' button in the Roles section > Members tab. An Owner can eject anyone except another Owner. If you're not an Owner, a Member can be ejected from a group if, and only if, they're only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the 'Remove Members from Roles' Ability."
|
||||
name="member eject" value="2" />
|
||||
<action
|
||||
<action description="Manage ban list"
|
||||
longdescription="Allows the group member to ban / un-ban Residents from this group."
|
||||
name="allow ban" value="51" />
|
||||
<action
|
||||
description="Toggle 'Open Enrollment' and change 'Enrollment fee'"
|
||||
longdescription="Toggle 'Open Enrollment' to let new Members join without an invitation, and change the 'Enrollment fee' in the General section."
|
||||
name="member options" value="3" />
|
||||
|
|
|
|||
|
|
@ -3775,6 +3775,7 @@ Abuse Report</string>
|
|||
<string name="LocalEstimateUSD">US$ [AMOUNT]</string>
|
||||
|
||||
<!-- Group Profile roles and powers -->
|
||||
<string name="Group Ban">Group Ban</string>
|
||||
<string name="Membership">Membership</string>
|
||||
<string name="Roles">Roles</string>
|
||||
<string name="Group Identity">Group Identity</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue