Group Bans!
Thankies Baker Linden~ Ported Ansariel's mAvatarNameCacheConnection change to mAvatarNameCacheConnections to llpanelgroupbulkimpl.h Adds setGroupID in places, in case we ever want to add that.. but for now we don't really need/use it Adds Refresh_Off icon from upstream. Viewer Interesting changes: Moves LLGroupChange out of stdenums.h into llgroupmgr.h Moves roles_constants.h from llcommon into newview This looks like it's better without space changes...
This commit is contained in:
@@ -254,7 +254,6 @@ set(llcommon_HEADER_FILES
|
||||
metapropertyt.h
|
||||
reflective.h
|
||||
reflectivet.h
|
||||
roles_constants.h
|
||||
stdenums.h
|
||||
stdtypes.h
|
||||
string_table.h
|
||||
|
||||
@@ -118,16 +118,6 @@ enum EAddPosition
|
||||
ADD_BOTTOM
|
||||
};
|
||||
|
||||
enum LLGroupChange
|
||||
{
|
||||
GC_PROPERTIES,
|
||||
GC_MEMBER_DATA,
|
||||
GC_ROLE_DATA,
|
||||
GC_ROLE_MEMBER_DATA,
|
||||
GC_TITLES,
|
||||
GC_ALL
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// DEPRECATED - create new, more specific files for shared enums/constants
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -936,6 +936,7 @@ P(fetchScriptLimitsRegionSummaryResponder);
|
||||
P(fnPtrResponder);
|
||||
P(floaterPermsResponder);
|
||||
P2(gamingDataReceived, transfer_22s_connect_10s);
|
||||
P(groupBanDataResponder);
|
||||
P2(groupMemberDataResponder, transfer_300s);
|
||||
P2(groupProposalBallotResponder, transfer_300s);
|
||||
P(homeLocationResponder);
|
||||
|
||||
@@ -216,6 +216,7 @@ set(viewer_SOURCE_FILES
|
||||
llfloaterfriends.cpp
|
||||
llfloatergesture.cpp
|
||||
llfloatergodtools.cpp
|
||||
llfloatergroupbulkban.cpp
|
||||
llfloatergroupinfo.cpp
|
||||
llfloatergroupinvite.cpp
|
||||
llfloatergroups.cpp
|
||||
@@ -368,6 +369,8 @@ set(viewer_SOURCE_FILES
|
||||
llpanelface.cpp
|
||||
llpanelgeneral.cpp
|
||||
llpanelgroup.cpp
|
||||
llpanelgroupbulk.cpp
|
||||
llpanelgroupbulkban.cpp
|
||||
llpanelgroupgeneral.cpp
|
||||
llpanelgroupinvite.cpp
|
||||
llpanelgrouplandmoney.cpp
|
||||
@@ -739,6 +742,7 @@ set(viewer_HEADER_FILES
|
||||
llfloaterfriends.h
|
||||
llfloatergesture.h
|
||||
llfloatergodtools.h
|
||||
llfloatergroupbulkban.h
|
||||
llfloatergroupinfo.h
|
||||
llfloatergroupinvite.h
|
||||
llfloatergroups.h
|
||||
@@ -891,6 +895,9 @@ set(viewer_HEADER_FILES
|
||||
llpanelface.h
|
||||
llpanelgeneral.h
|
||||
llpanelgroup.h
|
||||
llpanelgroupbulk.h
|
||||
llpanelgroupbulkban.h
|
||||
llpanelgroupbulkimpl.h
|
||||
llpanelgroupgeneral.h
|
||||
llpanelgroupinvite.h
|
||||
llpanelgrouplandmoney.h
|
||||
@@ -1117,6 +1124,7 @@ set(viewer_HEADER_FILES
|
||||
rlvinventory.h
|
||||
rlvlocks.h
|
||||
rlvui.h
|
||||
roles_constants.h
|
||||
scriptcounter.h
|
||||
sgmemstat.h
|
||||
sgversion.h
|
||||
|
||||
131
indra/newview/llfloatergroupbulkban.cpp
Normal file
131
indra/newview/llfloatergroupbulkban.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @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"
|
||||
|
||||
const LLRect FGB_RECT(0, 320, 210, 0);
|
||||
|
||||
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->close();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
LLFloaterGroupBulkBan::LLFloaterGroupBulkBan(const std::string& name,
|
||||
const LLRect &rect,
|
||||
const std::string& title,
|
||||
const LLUUID& group_id)
|
||||
: LLFloater(name, rect, title)
|
||||
{
|
||||
S32 floater_header_size = LLFLOATER_HEADER_SIZE;
|
||||
LLRect contents(getRect());
|
||||
contents.mTop -= floater_header_size;
|
||||
|
||||
mImpl = new impl(group_id);
|
||||
mImpl->mBulkBanPanelp = new LLPanelGroupBulkBan(group_id);
|
||||
|
||||
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)
|
||||
{
|
||||
// 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("groupban",
|
||||
FGB_RECT,
|
||||
"Group Ban",
|
||||
group_id);
|
||||
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->open();
|
||||
fgb->mImpl->mBulkBanPanelp->update();
|
||||
}
|
||||
51
indra/newview/llfloatergroupbulkban.h
Normal file
51
indra/newview/llfloatergroupbulkban.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @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 std::string& name,
|
||||
const LLRect& rect,
|
||||
const std::string& title,
|
||||
const LLUUID& group_id = LLUUID::null);
|
||||
|
||||
class impl;
|
||||
impl* mImpl;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERGROUPBULKBAN_H
|
||||
@@ -155,7 +155,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)
|
||||
@@ -165,9 +165,6 @@ public:
|
||||
else if (!gdatap->isMemberDataComplete())
|
||||
{
|
||||
llwarns << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
processGroupData();
|
||||
mRequestProcessed = true;
|
||||
}
|
||||
|
||||
@@ -232,11 +232,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();
|
||||
@@ -425,7 +425,7 @@ void LLGroupMgrGroupData::removeMemberData()
|
||||
delete mi->second;
|
||||
}
|
||||
mMembers.clear();
|
||||
mMemberDataComplete = FALSE;
|
||||
mMemberDataComplete = false;
|
||||
mMemberVersion.generate();
|
||||
}
|
||||
|
||||
@@ -447,8 +447,8 @@ void LLGroupMgrGroupData::removeRoleData()
|
||||
}
|
||||
mRoles.clear();
|
||||
mReceivedRoleMemberPairs = 0;
|
||||
mRoleDataComplete = FALSE;
|
||||
mRoleMemberDataComplete = FALSE;
|
||||
mRoleDataComplete = false;
|
||||
mRoleMemberDataComplete = false;
|
||||
}
|
||||
|
||||
void LLGroupMgrGroupData::removeRoleMemberData()
|
||||
@@ -472,7 +472,7 @@ void LLGroupMgrGroupData::removeRoleMemberData()
|
||||
}
|
||||
|
||||
mReceivedRoleMemberPairs = 0;
|
||||
mRoleMemberDataComplete = FALSE;
|
||||
mRoleMemberDataComplete = false;
|
||||
}
|
||||
|
||||
LLGroupMgrGroupData::~LLGroupMgrGroupData()
|
||||
@@ -825,6 +825,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
|
||||
//
|
||||
@@ -1039,12 +1053,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);
|
||||
}
|
||||
}
|
||||
@@ -1114,7 +1128,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);
|
||||
@@ -1189,12 +1203,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);
|
||||
}
|
||||
}
|
||||
@@ -1306,7 +1320,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
|
||||
}
|
||||
}
|
||||
|
||||
group_datap->mRoleMemberDataComplete = TRUE;
|
||||
group_datap->mRoleMemberDataComplete = true;
|
||||
group_datap->mRoleMembersRequestID.setNull();
|
||||
}
|
||||
|
||||
@@ -1934,8 +1948,149 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
|
||||
|
||||
|
||||
class AIHTTPTimeoutPolicy;
|
||||
extern AIHTTPTimeoutPolicy groupBanDataResponder_timeout;
|
||||
extern AIHTTPTimeoutPolicy groupMemberDataResponder_timeout;
|
||||
|
||||
// Responder class for capability group management
|
||||
class GroupBanDataResponder : public LLHTTPClient::ResponderWithResult
|
||||
{
|
||||
public:
|
||||
GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false);
|
||||
virtual ~GroupBanDataResponder() {}
|
||||
virtual void result(const LLSD& mContent); //httpSuccess();
|
||||
virtual void error(U32 mStatus, const std::string& mContent); //httpFailure();
|
||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupBanDataResponder_timeout; }
|
||||
/*virtual*/ char const* getName(void) const { return "GroupBanDataResponder"; }
|
||||
private:
|
||||
LLUUID mGroupID;
|
||||
BOOL mForceRefresh;
|
||||
};
|
||||
|
||||
GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) :
|
||||
mGroupID(gropup_id),
|
||||
mForceRefresh(force_refresh)
|
||||
{}
|
||||
|
||||
//void GroupBanDataResponder::httpFailure()
|
||||
void GroupBanDataResponder::error(U32 mStatus, const std::string& mContent)
|
||||
{
|
||||
LL_WARNS("GrpMgr") << "Error receiving group member data [status:"
|
||||
<< mStatus << "]: " << mContent << LL_ENDL;
|
||||
}
|
||||
|
||||
//void GroupBanDataResponder::httpSuccess()
|
||||
void GroupBanDataResponder::result(const LLSD& mContent)
|
||||
{
|
||||
if (mContent.size())
|
||||
{
|
||||
if (mContent.has("ban_list"))
|
||||
{
|
||||
// group ban data received
|
||||
LLGroupMgr::processGroupBanRequest(mContent);
|
||||
mForceRefresh = false;
|
||||
}
|
||||
}
|
||||
if (mForceRefresh)
|
||||
{
|
||||
// no ban data received, refreshing data 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::ResponderWithResult
|
||||
{
|
||||
@@ -2104,12 +2259,12 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
|
||||
if (group_datap->mTitles.size() < 1)
|
||||
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)
|
||||
{
|
||||
group_datap->mPendingRoleMemberRequest = FALSE;
|
||||
group_datap->mPendingRoleMemberRequest = false;
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,21 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// Forward Declarations
|
||||
class LLMessageSystem;
|
||||
class LLGroupRoleData;
|
||||
class LLGroupMgr;
|
||||
|
||||
enum LLGroupChange
|
||||
{
|
||||
GC_PROPERTIES,
|
||||
GC_MEMBER_DATA,
|
||||
GC_ROLE_DATA,
|
||||
GC_ROLE_MEMBER_DATA,
|
||||
GC_TITLES,
|
||||
GC_BANLIST,
|
||||
GC_ALL
|
||||
};
|
||||
|
||||
class LLGroupMgrObserver
|
||||
{
|
||||
@@ -54,8 +68,6 @@ public:
|
||||
virtual void changed(const LLUUID& group_id, LLGroupChange gc) = 0;
|
||||
};
|
||||
|
||||
class LLGroupRoleData;
|
||||
|
||||
class LLGroupMemberData
|
||||
{
|
||||
friend class LLGroupMgrGroupData;
|
||||
@@ -190,6 +202,17 @@ struct lluuid_pair_less
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct LLGroupBanData
|
||||
{
|
||||
LLGroupBanData() : mBanDate() {}
|
||||
~LLGroupBanData() {}
|
||||
|
||||
LLDate mBanDate;
|
||||
// TODO: std::string ban_reason;
|
||||
};
|
||||
|
||||
|
||||
struct LLGroupTitle
|
||||
{
|
||||
std::string mTitle;
|
||||
@@ -197,8 +220,6 @@ struct LLGroupTitle
|
||||
BOOL mSelected;
|
||||
};
|
||||
|
||||
class LLGroupMgr;
|
||||
|
||||
class LLGroupMgrGroupData
|
||||
{
|
||||
friend class LLGroupMgr;
|
||||
@@ -228,26 +249,36 @@ 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; }
|
||||
|
||||
F32 getAccessTime() const { return mAccessTime; }
|
||||
void setAccessed();
|
||||
|
||||
const LLUUID& getMemberVersion() const { return mMemberVersion; }
|
||||
|
||||
void clearBanList() { mBanList.clear(); }
|
||||
void getBanList(const LLUUID& ban_i, const LLGroupBanData& ban_data = LLGroupBanData());
|
||||
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;
|
||||
|
||||
@@ -277,12 +308,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
|
||||
@@ -309,6 +340,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();
|
||||
@@ -343,6 +391,13 @@ public:
|
||||
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);
|
||||
|
||||
void sendCapGroupMembersRequest(const LLUUID& group_id);
|
||||
static void processCapGroupMembersRequest(const LLSD& content);
|
||||
|
||||
@@ -387,4 +442,3 @@ private:
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,7 +53,8 @@ LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL
|
||||
: LLScrollListCtrl(name, rect, NULL, allow_multiple_selection, draw_border,draw_heading),
|
||||
mNameColumnIndex(name_column_index),
|
||||
mAllowCallingCardDrop(false),
|
||||
mNameSystem(name_system)
|
||||
mNameSystem(name_system),
|
||||
mPendingLookupsRemaining(0)
|
||||
{
|
||||
setToolTip(tooltip);
|
||||
}
|
||||
@@ -203,6 +204,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 mPendingLookupsRemainig might
|
||||
// go negative. So just reset it right now and figure out if it's
|
||||
// possible later :)
|
||||
mPendingLookupsRemaining = 0;
|
||||
mNameListCompleteSignal(false);
|
||||
}
|
||||
mPendingLookupsRemaining++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -254,6 +266,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
|
||||
{
|
||||
selectNthItem(idx); // not sure whether this is needed, taken from previous implementation
|
||||
deleteSingleItem(idx);
|
||||
|
||||
mPendingLookupsRemaining--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,6 +306,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,8 @@ class LLNameListCtrl
|
||||
: public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl>
|
||||
{
|
||||
public:
|
||||
typedef boost::signals2::signal<void(bool)> namelist_complete_signal_t;
|
||||
|
||||
typedef enum e_name_type
|
||||
{
|
||||
INDIVIDUAL,
|
||||
@@ -155,6 +157,16 @@ private:
|
||||
const LLCachedControl<S32> mNameSystem;
|
||||
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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ LLPanelGroup::LLPanelGroup(const LLUUID& group_id)
|
||||
mFactoryMap["members_sub_tab"] = LLCallbackMap(LLPanelGroupMembersSubTab::createTab, &mID);
|
||||
mFactoryMap["roles_sub_tab"] = LLCallbackMap(LLPanelGroupRolesSubTab::createTab, &mID);
|
||||
mFactoryMap["actions_sub_tab"] = LLCallbackMap(LLPanelGroupActionsSubTab::createTab, &mID);
|
||||
mFactoryMap["banlist_sub_tab"] = LLCallbackMap(LLPanelGroupBanListSubTab::createTab, &mID);
|
||||
|
||||
LLGroupMgr::getInstance()->addObserver(this);
|
||||
|
||||
|
||||
@@ -168,12 +168,16 @@ public:
|
||||
|
||||
virtual BOOL isVisibleByAgent(LLAgent* agentp);
|
||||
|
||||
virtual void setGroupID(const LLUUID& id) { mGroupID = id; }
|
||||
|
||||
void setAllowEdit(BOOL v) { mAllowEdit = v; }
|
||||
|
||||
void addObserver(LLPanelGroupTabObserver *obs);
|
||||
void removeObserver(LLPanelGroupTabObserver *obs);
|
||||
void notifyObservers();
|
||||
|
||||
const LLUUID& getGroupID() const { return mGroupID; }
|
||||
|
||||
protected:
|
||||
LLUUID mGroupID;
|
||||
LLTabContainer* mTabContainer;
|
||||
|
||||
424
indra/newview/llpanelgroupbulk.cpp
Normal file
424
indra/newview/llpanelgroupbulk.cpp
Normal file
@@ -0,0 +1,424 @@
|
||||
/**
|
||||
* @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),
|
||||
mRoleNames(NULL),
|
||||
mOwnerWarning(),
|
||||
mAlreadyInGroup(),
|
||||
mConfirmedOwnerInvite(false),
|
||||
mListFullNotificationSent(false)
|
||||
{}
|
||||
|
||||
LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl()
|
||||
{
|
||||
for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
|
||||
{
|
||||
if (it->second.connected())
|
||||
{
|
||||
it->second.disconnect();
|
||||
}
|
||||
}
|
||||
mAvatarNameCacheConnections.clear();
|
||||
}
|
||||
|
||||
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
|
||||
/* Singu Note: We're different, we don't do this..
|
||||
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);
|
||||
boost::bind(&LLPanelGroupBulkImpl::callbackAddUsers, panelp->mImplementation, _1), TRUE);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mAvatarNameCacheConnections[agent_ids[i]].connected())
|
||||
{
|
||||
mAvatarNameCacheConnections[agent_ids[i]].disconnect();
|
||||
}
|
||||
// *TODO : Add a callback per avatar name being fetched.
|
||||
mAvatarNameCacheConnections[agent_ids[i]] = LLAvatarNameCache::get(agent_ids[i],boost::bind(&LLPanelGroupBulkImpl::onAvatarNameCache, this, _1, _2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkImpl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
|
||||
{
|
||||
if (mAvatarNameCacheConnections[agent_id].connected())
|
||||
{
|
||||
mAvatarNameCacheConnections[agent_id].disconnect();
|
||||
}
|
||||
std::vector<std::string> names;
|
||||
uuid_vec_t agent_ids;
|
||||
agent_ids.push_back(agent_id);
|
||||
std::string name;
|
||||
LLAvatarNameCache::getPNSName(av_name, name);
|
||||
names.push_back(name);
|
||||
|
||||
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);
|
||||
std::string name;
|
||||
LLAvatarNameCache::getPNSName(av_name, name);
|
||||
names.push_back(name);
|
||||
|
||||
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
|
||||
{
|
||||
std::string name;
|
||||
LLAvatarNameCache::getPNSName(av_name, name);
|
||||
names.push_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mImplementation->mListFullNotificationSent = false;
|
||||
mImplementation->addUsers(names, agent_ids);
|
||||
}
|
||||
|
||||
73
indra/newview/llpanelgroupbulk.h
Normal file
73
indra/newview/llpanelgroupbulk.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @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
|
||||
160
indra/newview/llpanelgroupbulkban.cpp
Normal file
160
indra/newview/llpanelgroupbulkban.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* @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 "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");
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "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->setCommitCallback(boost::bind(&LLPanelGroupBulkBan::submit, 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");
|
||||
|
||||
update();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelGroupBulkBan::submit()
|
||||
{
|
||||
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_GROUP_BANS = 100; // Max invites per request. 100 to match server cap.
|
||||
if (banned_agent_list.size() > MAX_GROUP_BANS)
|
||||
{
|
||||
// Fail!
|
||||
LLSD msg;
|
||||
msg["MESSAGE"] = mImplementation->mTooManySelected;
|
||||
LLNotificationsUtil::add("GenericAlert", msg);
|
||||
(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);
|
||||
return;
|
||||
}
|
||||
|
||||
LLGroupMgrGroupData * group_datap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID);
|
||||
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;
|
||||
if (std::find(banned_agent_list.begin(), banned_agent_list.end(), group_ban_agent_id) != banned_agent_list.end())
|
||||
{
|
||||
// Fail!
|
||||
std::string av_name;
|
||||
LLAvatarNameCache::getPNSName(group_ban_agent_id, av_name);
|
||||
|
||||
LLStringUtil::format_map_t string_args;
|
||||
string_args["[RESIDENT]"] = av_name;
|
||||
|
||||
LLSD msg;
|
||||
msg["MESSAGE"] = getString("already_banned", string_args);
|
||||
LLNotificationsUtil::add("GenericAlert", msg);
|
||||
(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//then close
|
||||
(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);
|
||||
}
|
||||
46
indra/newview/llpanelgroupbulkban.h
Normal file
46
indra/newview/llpanelgroupbulkban.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @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();
|
||||
|
||||
virtual void submit();
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELGROUPBULKBAN_H
|
||||
96
indra/newview/llpanelgroupbulkimpl.h
Normal file
96
indra/newview/llpanelgroupbulkimpl.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @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);
|
||||
void callbackAddUsers(const uuid_vec_t& agent_ids);
|
||||
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
|
||||
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::set<LLUUID> mInviteeIDs;
|
||||
|
||||
void (*mCloseCallback)(void* data);
|
||||
void* mCloseCallbackUserData;
|
||||
typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
|
||||
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
|
||||
|
||||
// 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
|
||||
@@ -258,7 +258,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,
|
||||
@@ -540,7 +540,7 @@ void LLPanelGroupInvite::updateLists()
|
||||
{
|
||||
waiting = true;
|
||||
}
|
||||
if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete())
|
||||
if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && gdatap->isRoleMemberDataComplete())
|
||||
{
|
||||
if ( mImplementation->mRoleNames )
|
||||
{
|
||||
@@ -568,6 +568,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;
|
||||
@@ -615,7 +616,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);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* @file llpanelgrouproles.cpp
|
||||
* @brief Panel for roles information about a particular group.
|
||||
*
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llbutton.h"
|
||||
#include "llfiltereditor.h"
|
||||
#include "llfloatergroupbulkban.h"
|
||||
#include "llfloatergroupinvite.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "lllineeditor.h"
|
||||
@@ -109,6 +110,9 @@ bool agentCanAddToRole(const LLUUID& group_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// LLPanelGroupRoles /////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
void* LLPanelGroupRoles::createTab(void* data)
|
||||
{
|
||||
@@ -308,7 +312,6 @@ bool LLPanelGroupRoles::onModalClose(const LLSD& notification, const LLSD& respo
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LLPanelGroupRoles::apply(std::string& mesg)
|
||||
{
|
||||
// Pass this along to the currently visible sub tab.
|
||||
@@ -374,39 +377,33 @@ void LLPanelGroupRoles::activate()
|
||||
{
|
||||
// Start requesting member and role data if needed.
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
//if (!gdatap || mFirstUse)
|
||||
if (!gdatap || !gdatap->isMemberDataComplete())
|
||||
{
|
||||
// Check member data.
|
||||
|
||||
if (!gdatap || !gdatap->isMemberDataComplete() )
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
// Check role data.
|
||||
if (!gdatap || !gdatap->isRoleDataComplete() )
|
||||
{
|
||||
// Mildly hackish - clear all pending changes
|
||||
cancel();
|
||||
|
||||
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
|
||||
}
|
||||
|
||||
// Check role-member mapping data.
|
||||
if (!gdatap || !gdatap->isRoleMemberDataComplete() )
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
// Need this to get base group member powers
|
||||
if (!gdatap || !gdatap->isGroupPropertiesDataComplete() )
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
|
||||
}
|
||||
|
||||
mFirstUse = FALSE;
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
if (!gdatap || !gdatap->isRoleDataComplete() )
|
||||
{
|
||||
// Mildly hackish - clear all pending changes
|
||||
cancel();
|
||||
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
// Check role-member mapping data.
|
||||
if (!gdatap || !gdatap->isRoleMemberDataComplete() )
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
// Need this to get base group member powers
|
||||
if (!gdatap || !gdatap->isGroupPropertiesDataComplete() )
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
|
||||
}
|
||||
|
||||
mFirstUse = FALSE;
|
||||
|
||||
LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
|
||||
if (panelp) panelp->activate();
|
||||
}
|
||||
@@ -441,14 +438,38 @@ void LLPanelGroupRoles::tabChanged()
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// LLPanelGroupSubTab
|
||||
////////////////////////////
|
||||
void LLPanelGroupRoles::setGroupID(const LLUUID& id)
|
||||
{
|
||||
LLPanelGroupTab::setGroupID(id);
|
||||
|
||||
LLPanelGroupMembersSubTab* group_members_tab = findChild<LLPanelGroupMembersSubTab>("members_sub_tab");
|
||||
LLPanelGroupRolesSubTab* group_roles_tab = findChild<LLPanelGroupRolesSubTab>("roles_sub_tab");
|
||||
LLPanelGroupActionsSubTab* group_actions_tab = findChild<LLPanelGroupActionsSubTab>("actions_sub_tab");
|
||||
LLPanelGroupBanListSubTab* group_ban_tab = findChild<LLPanelGroupBanListSubTab>("banlist_sub_tab");
|
||||
|
||||
if (group_members_tab) group_members_tab->setGroupID(id);
|
||||
if (group_roles_tab) group_roles_tab->setGroupID(id);
|
||||
if (group_actions_tab) group_actions_tab->setGroupID(id);
|
||||
if (group_ban_tab) group_ban_tab->setGroupID(id);
|
||||
|
||||
LLButton* button = getChild<LLButton>("member_invite");
|
||||
if (button)
|
||||
button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE));
|
||||
|
||||
if (mSubTabContainer)
|
||||
mSubTabContainer->selectTab(1);
|
||||
group_roles_tab->mFirstOpen = TRUE;
|
||||
activate();
|
||||
}
|
||||
|
||||
|
||||
// LLPanelGroupSubTab ////////////////////////////////////////////////////
|
||||
LLPanelGroupSubTab::LLPanelGroupSubTab(const std::string& name, const LLUUID& group_id)
|
||||
: LLPanelGroupTab(name, group_id),
|
||||
mHeader(NULL),
|
||||
mFooter(NULL),
|
||||
mActivated(false),
|
||||
mHasGroupBanPower(false),
|
||||
mSearchEditor(NULL)
|
||||
{
|
||||
}
|
||||
@@ -493,6 +514,17 @@ BOOL LLPanelGroupSubTab::postBuild()
|
||||
return LLPanelGroupTab::postBuild();
|
||||
}
|
||||
|
||||
void LLPanelGroupSubTab::setGroupID(const LLUUID& id)
|
||||
{
|
||||
LLPanelGroupTab::setGroupID(id);
|
||||
if(mSearchEditor)
|
||||
{
|
||||
mSearchEditor->clear();
|
||||
setSearchFilter("");
|
||||
}
|
||||
|
||||
mActivated = false;
|
||||
}
|
||||
|
||||
void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
|
||||
{
|
||||
@@ -559,9 +591,10 @@ void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl,
|
||||
return;
|
||||
}
|
||||
|
||||
mHasGroupBanPower = false;
|
||||
|
||||
std::vector<LLRoleActionSet*>::iterator ras_it = LLGroupMgr::getInstance()->mRoleActionSets.begin();
|
||||
std::vector<LLRoleActionSet*>::iterator ras_end = LLGroupMgr::getInstance()->mRoleActionSets.end();
|
||||
|
||||
for ( ; ras_it != ras_end; ++ras_it)
|
||||
{
|
||||
buildActionCategory(ctrl,
|
||||
@@ -685,6 +718,33 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
|
||||
row["columns"][column_index]["value"] = (*ra_it)->mDescription;
|
||||
row["columns"][column_index]["font"] = "SANSSERIF_SMALL";
|
||||
|
||||
if (mHasGroupBanPower)
|
||||
{
|
||||
// The ban ability is being set. Prevent these abilities from being manipulated
|
||||
if ((*ra_it)->mPowerBit == GP_MEMBER_EJECT)
|
||||
{
|
||||
row["enabled"] = false;
|
||||
}
|
||||
else if ((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER)
|
||||
{
|
||||
row["enabled"] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Singu Note: enabled should not be set on here if it was turned off above for another reason... right? Oh well, we'll find out.
|
||||
*/
|
||||
// The ban ability is not set. Allow these abilities to be manipulated
|
||||
if ((*ra_it)->mPowerBit == GP_MEMBER_EJECT)
|
||||
{
|
||||
row["enabled"] = true;
|
||||
}
|
||||
else if ((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER)
|
||||
{
|
||||
row["enabled"] = true;
|
||||
}
|
||||
}
|
||||
|
||||
LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it));
|
||||
|
||||
if (-1 != check_box_index)
|
||||
@@ -720,6 +780,15 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
|
||||
check->setTentative(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Regardless of whether or not this ability is allowed by all or some, we want to prevent
|
||||
// the group managers from accidentally disabling either of the two additional abilities
|
||||
// tied with GP_GROUP_BAN_ACCESS
|
||||
if ( (allowed_by_all & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS ||
|
||||
(allowed_by_some & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS)
|
||||
{
|
||||
mHasGroupBanPower = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,10 +808,7 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// LLPanelGroupMembersSubTab
|
||||
////////////////////////////
|
||||
|
||||
// LLPanelGroupMembersSubTab /////////////////////////////////////////////
|
||||
// static
|
||||
void* LLPanelGroupMembersSubTab::createTab(void* data)
|
||||
{
|
||||
@@ -812,9 +878,27 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)
|
||||
mEjectBtn->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
mBanBtn = parent->getChild<LLButton>("member_ban", recurse);
|
||||
if (mBanBtn)
|
||||
{
|
||||
mBanBtn->setClickedCallback(boost::bind(&LLPanelGroupMembersSubTab::handleBanMember,this));
|
||||
mBanBtn->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id)
|
||||
{
|
||||
//clear members list
|
||||
if(mMembersList) mMembersList->deleteAllItems();
|
||||
if(mAssignedRolesList) mAssignedRolesList->deleteAllItems();
|
||||
if(mAllowedActionsList) mAllowedActionsList->deleteAllItems();
|
||||
|
||||
LLPanelGroupSubTab::setGroupID(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// static
|
||||
void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data)
|
||||
@@ -844,7 +928,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
|
||||
|
||||
// Build a vector of all selected members, and gather allowed actions.
|
||||
uuid_vec_t selected_members;
|
||||
U64 allowed_by_all = 0xffffffffffffLL;
|
||||
U64 allowed_by_all = GP_ALL_POWERS; //0xffffffffffffLL;
|
||||
U64 allowed_by_some = 0;
|
||||
|
||||
std::vector<LLScrollListItem*>::iterator itor;
|
||||
@@ -881,8 +965,8 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
|
||||
LLGroupMgrGroupData::role_list_t::iterator iter = gdatap->mRoles.begin();
|
||||
LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end();
|
||||
|
||||
BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID,
|
||||
GP_MEMBER_EJECT);
|
||||
BOOL can_ban_members = gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS);
|
||||
BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT);
|
||||
BOOL member_is_owner = FALSE;
|
||||
|
||||
for( ; iter != end; ++iter)
|
||||
@@ -929,6 +1013,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
|
||||
{
|
||||
// Can't remove other owners.
|
||||
cb_enable = FALSE;
|
||||
can_ban_members = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1012,7 +1097,10 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
|
||||
mAssignedRolesList->setEnabled(TRUE);
|
||||
|
||||
if (gAgent.isGodlike())
|
||||
{
|
||||
can_eject_members = TRUE;
|
||||
can_ban_members = TRUE;
|
||||
}
|
||||
|
||||
if (!can_eject_members && !member_is_owner)
|
||||
{
|
||||
@@ -1025,10 +1113,41 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
|
||||
if ( member_data && member_data->isInRole(gdatap->mOwnerRole) )
|
||||
{
|
||||
can_eject_members = TRUE;
|
||||
can_ban_members = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ... or we can eject them because we have all the requisite powers...
|
||||
if ( gAgent.hasPowerInGroup(mGroupID, GP_ROLE_REMOVE_MEMBER) &&
|
||||
!member_is_owner)
|
||||
{
|
||||
if (gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT))
|
||||
{
|
||||
can_eject_members = TRUE;
|
||||
}
|
||||
|
||||
if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS))
|
||||
{
|
||||
can_ban_members = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uuid_vec_t::const_iterator member_iter = selected_members.begin();
|
||||
uuid_vec_t::const_iterator member_end = selected_members.end();
|
||||
for ( ; member_iter != member_end; ++member_iter)
|
||||
{
|
||||
// Don't count the agent.
|
||||
if ((*member_iter) == gAgent.getID())
|
||||
{
|
||||
can_eject_members = FALSE;
|
||||
can_ban_members = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
mBanBtn->setEnabled(can_ban_members);
|
||||
mEjectBtn->setEnabled(can_eject_members);
|
||||
}
|
||||
|
||||
@@ -1098,7 +1217,9 @@ void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, c
|
||||
for (uuid_vec_t::const_iterator i = selected_members.begin(); i != selected_members.end(); ++i)
|
||||
{
|
||||
LLSD args;
|
||||
args["AVATAR_NAME"] = LLSLURL("agent", *i, "displayname").getSLURLString();
|
||||
std::string av_name;
|
||||
LLAvatarNameCache::getPNSName(*i, av_name);
|
||||
args["AVATAR_NAME"] = av_name;
|
||||
args["GROUP_NAME"] = group_data->mName;
|
||||
|
||||
LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
|
||||
@@ -1114,12 +1235,11 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
|
||||
|
||||
//add that the user is requesting to change the roles for selected
|
||||
//members
|
||||
U64 powers_all_have = 0xffffffffffffLL;
|
||||
U64 powers_all_have = GP_ALL_POWERS;
|
||||
U64 powers_some_have = 0;
|
||||
|
||||
BOOL is_owner_role = ( gdatap->mOwnerRole == role_id );
|
||||
LLUUID member_id;
|
||||
|
||||
|
||||
std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
|
||||
if (selection.empty())
|
||||
@@ -1130,7 +1250,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
|
||||
for (std::vector<LLScrollListItem*>::iterator itor = selection.begin() ;
|
||||
itor != selection.end(); ++itor)
|
||||
{
|
||||
|
||||
member_id = (*itor)->getUUID();
|
||||
|
||||
//see if we requested a change for this member before
|
||||
@@ -1196,7 +1315,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data)
|
||||
{
|
||||
@@ -1567,15 +1685,15 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data)
|
||||
LLNameListCtrl::NameItem item_params;
|
||||
item_params.value = data->getID();
|
||||
|
||||
item_params.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/;
|
||||
item_params.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL");
|
||||
|
||||
item_params.columns.add().column("donated").value(donated.getString())
|
||||
.font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/;
|
||||
.font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL");
|
||||
|
||||
static const LLCachedControl<std::string> format(gSavedSettings, "ShortDateFormat");
|
||||
item_params.columns.add().column("online").value(data->getOnlineStatus())
|
||||
.format(format).type(is_online_status_string(data->getOnlineStatus()) ? "text" : "date")
|
||||
.font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/;
|
||||
.font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL");
|
||||
mMembersList->addNameItemRow(item_params);
|
||||
|
||||
mHasMatch = TRUE;
|
||||
@@ -1642,7 +1760,6 @@ void LLPanelGroupMembersSubTab::updateMembers()
|
||||
mMembersList->deleteAllItems();
|
||||
}
|
||||
|
||||
|
||||
LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
|
||||
|
||||
LLTimer update_time;
|
||||
@@ -1700,12 +1817,35 @@ void LLPanelGroupMembersSubTab::updateMembers()
|
||||
handleMemberSelect();
|
||||
}
|
||||
|
||||
void LLPanelGroupMembersSubTab::handleBanMember()
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
if (!gdatap)
|
||||
{
|
||||
LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Singu Note: We have this function, so there's less code here.
|
||||
uuid_vec_t ban_ids = mMembersList->getSelectedIDs();
|
||||
if (ban_ids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uuid_vec_t::iterator itor;
|
||||
for(itor = ban_ids.begin(); itor != ban_ids.end(); ++itor)
|
||||
{
|
||||
LLGroupBanData ban_data;
|
||||
gdatap->createBanEntry(*itor, ban_data);
|
||||
}
|
||||
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_CREATE, ban_ids);
|
||||
handleEjectMembers();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////
|
||||
// LLPanelGroupRolesSubTab
|
||||
////////////////////////////
|
||||
|
||||
// LLPanelGroupRolesSubTab ///////////////////////////////////////////////
|
||||
// static
|
||||
void* LLPanelGroupRolesSubTab::createTab(void* data)
|
||||
{
|
||||
@@ -1724,7 +1864,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const std::string& name, const
|
||||
mMemberVisibleCheck(NULL),
|
||||
mDeleteRoleButton(NULL),
|
||||
mCreateRoleButton(NULL),
|
||||
|
||||
mFirstOpen(TRUE),
|
||||
mHasRoleChange(FALSE)
|
||||
{
|
||||
}
|
||||
@@ -1824,6 +1964,7 @@ void LLPanelGroupRolesSubTab::deactivate()
|
||||
lldebugs << "LLPanelGroupRolesSubTab::deactivate()" << llendl;
|
||||
|
||||
LLPanelGroupSubTab::deactivate();
|
||||
mFirstOpen = FALSE;
|
||||
}
|
||||
|
||||
bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg)
|
||||
@@ -1831,6 +1972,12 @@ bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg)
|
||||
lldebugs << "LLPanelGroupRolesSubTab::needsApply()" << llendl;
|
||||
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
if (!gdatap)
|
||||
{
|
||||
llwarns << "Unable to get group data for group " << mGroupID << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return (mHasRoleChange // Text changed in current role
|
||||
|| (gdatap && gdatap->pendingRoleChanges())); // Pending role changes in the group
|
||||
@@ -1841,7 +1988,7 @@ bool LLPanelGroupRolesSubTab::apply(std::string& mesg)
|
||||
lldebugs << "LLPanelGroupRolesSubTab::apply()" << llendl;
|
||||
|
||||
saveRoleChanges(true);
|
||||
|
||||
mFirstOpen = FALSE;
|
||||
LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID);
|
||||
|
||||
notifyObservers();
|
||||
@@ -1978,14 +2125,17 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
|
||||
}
|
||||
}
|
||||
|
||||
if (!gdatap || !gdatap->isMemberDataComplete())
|
||||
if (!mFirstOpen)
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
if (!gdatap || !gdatap->isRoleMemberDataComplete())
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
|
||||
if (!gdatap || !gdatap->isMemberDataComplete())
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
if (!gdatap || !gdatap->isRoleMemberDataComplete())
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
|
||||
}
|
||||
}
|
||||
|
||||
if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc)
|
||||
@@ -2001,6 +2151,9 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
|
||||
void LLPanelGroupRolesSubTab::onRoleSelect(LLUICtrl* ctrl, void* user_data)
|
||||
{
|
||||
LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
self->handleRoleSelect();
|
||||
}
|
||||
|
||||
@@ -2180,41 +2333,116 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force)
|
||||
LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata();
|
||||
U64 power = rap->mPowerBit;
|
||||
|
||||
if (check->get())
|
||||
bool isEnablingAbility = check->get();
|
||||
LLRoleData rd;
|
||||
LLSD args;
|
||||
|
||||
if (isEnablingAbility &&
|
||||
!force &&
|
||||
((GP_ROLE_ASSIGN_MEMBER == power) || (GP_ROLE_CHANGE_ACTIONS == power) ))
|
||||
{
|
||||
if (!force && ( (GP_ROLE_ASSIGN_MEMBER == power)
|
||||
|| (GP_ROLE_CHANGE_ACTIONS == power) ))
|
||||
// Uncheck the item, for now. It will be
|
||||
// checked if they click 'Yes', below.
|
||||
check->set(FALSE);
|
||||
|
||||
LLRoleData rd;
|
||||
LLSD args;
|
||||
|
||||
if ( gdatap->getRoleData(role_id, rd) )
|
||||
{
|
||||
// Uncheck the item, for now. It will be
|
||||
// checked if they click 'Yes', below.
|
||||
check->set(FALSE);
|
||||
|
||||
LLRoleData rd;
|
||||
LLSD args;
|
||||
|
||||
if ( gdatap->getRoleData(role_id, rd) )
|
||||
args["ACTION_NAME"] = rap->mDescription;
|
||||
args["ROLE_NAME"] = rd.mRoleName;
|
||||
mHasModal = TRUE;
|
||||
std::string warning = "AssignDangerousActionWarning";
|
||||
if (GP_ROLE_CHANGE_ACTIONS == power)
|
||||
{
|
||||
args["ACTION_NAME"] = rap->mDescription;
|
||||
args["ROLE_NAME"] = rd.mRoleName;
|
||||
mHasModal = TRUE;
|
||||
std::string warning = "AssignDangerousActionWarning";
|
||||
if (GP_ROLE_CHANGE_ACTIONS == power)
|
||||
{
|
||||
warning = "AssignDangerousAbilityWarning";
|
||||
}
|
||||
LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check));
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Unable to look up role information for role id: "
|
||||
<< role_id << llendl;
|
||||
warning = "AssignDangerousAbilityWarning";
|
||||
}
|
||||
LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check));
|
||||
}
|
||||
else
|
||||
{
|
||||
gdatap->addRolePower(role_id,power);
|
||||
llwarns << "Unable to look up role information for role id: "
|
||||
<< role_id << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (GP_GROUP_BAN_ACCESS == power)
|
||||
{
|
||||
std::string warning = isEnablingAbility ? "AssignBanAbilityWarning" : "RemoveBanAbilityWarning";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Get role data for both GP_ROLE_REMOVE_MEMBER and GP_MEMBER_EJECT
|
||||
// Add description and role name to LLSD
|
||||
// Pop up dialog saying "Yo, you also granted these other abilities when you did this!"
|
||||
if (gdatap->getRoleData(role_id, rd))
|
||||
{
|
||||
args["ACTION_NAME"] = rap->mDescription;
|
||||
args["ROLE_NAME"] = rd.mRoleName;
|
||||
mHasModal = TRUE;
|
||||
|
||||
std::vector<LLScrollListItem*> all_data = mAllowedActionsList->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator ad_it = all_data.begin();
|
||||
std::vector<LLScrollListItem*>::iterator ad_end = all_data.end();
|
||||
LLRoleAction* adp;
|
||||
for( ; ad_it != ad_end; ++ad_it)
|
||||
{
|
||||
adp = (LLRoleAction*)(*ad_it)->getUserdata();
|
||||
if (adp->mPowerBit == GP_MEMBER_EJECT)
|
||||
{
|
||||
args["ACTION_NAME_2"] = adp->mDescription;
|
||||
}
|
||||
else if (adp->mPowerBit == GP_ROLE_REMOVE_MEMBER)
|
||||
{
|
||||
args["ACTION_NAME_3"] = adp->mDescription;
|
||||
}
|
||||
}
|
||||
|
||||
LLNotificationsUtil::add(warning, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Unable to look up role information for role id: "
|
||||
<< role_id << llendl;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.find(role_id);
|
||||
U64 current_role_powers = GP_NO_POWERS;
|
||||
if (rit != gdatap->mRoles.end())
|
||||
{
|
||||
current_role_powers = ((*rit).second->getRoleData().mRolePowers);
|
||||
}
|
||||
|
||||
if (isEnablingAbility)
|
||||
{
|
||||
power |= (GP_ROLE_REMOVE_MEMBER | GP_MEMBER_EJECT);
|
||||
current_role_powers |= power;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_role_powers &= ~GP_GROUP_BAN_ACCESS;
|
||||
}
|
||||
|
||||
mAllowedActionsList->deleteAllItems();
|
||||
buildActionsList( mAllowedActionsList,
|
||||
current_role_powers,
|
||||
current_role_powers,
|
||||
boost::bind(&LLPanelGroupRolesSubTab::handleActionCheck, this, _1, false),
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE);
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Adding non-specific ability to role
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (isEnablingAbility)
|
||||
{
|
||||
gdatap->addRolePower(role_id, power);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdatap->removeRolePower(role_id,power);
|
||||
@@ -2222,6 +2450,7 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force)
|
||||
|
||||
mHasRoleChange = TRUE;
|
||||
notifyObservers();
|
||||
|
||||
}
|
||||
|
||||
bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check)
|
||||
@@ -2241,7 +2470,6 @@ bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD&
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data)
|
||||
{
|
||||
@@ -2419,10 +2647,26 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role)
|
||||
mHasRoleChange = FALSE;
|
||||
}
|
||||
}
|
||||
////////////////////////////
|
||||
// LLPanelGroupActionsSubTab
|
||||
////////////////////////////
|
||||
|
||||
void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id)
|
||||
{
|
||||
if (mRolesList) mRolesList->deleteAllItems();
|
||||
if (mAssignedMembersList) mAssignedMembersList->deleteAllItems();
|
||||
if (mAllowedActionsList) mAllowedActionsList->deleteAllItems();
|
||||
|
||||
if (mRoleName) mRoleName->clear();
|
||||
if (mRoleDescription) mRoleDescription->clear();
|
||||
if (mRoleTitle) mRoleTitle->clear();
|
||||
|
||||
mHasRoleChange = FALSE;
|
||||
|
||||
setFooterEnabled(FALSE);
|
||||
|
||||
LLPanelGroupSubTab::setGroupID(id);
|
||||
}
|
||||
|
||||
|
||||
// LLPanelGroupActionsSubTab /////////////////////////////////////////////
|
||||
// static
|
||||
void* LLPanelGroupActionsSubTab::createTab(void* data)
|
||||
{
|
||||
@@ -2600,3 +2844,223 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
|
||||
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id)
|
||||
{
|
||||
if (mActionList) mActionList->deleteAllItems();
|
||||
if (mActionRoles) mActionRoles->deleteAllItems();
|
||||
if (mActionMembers) mActionMembers->deleteAllItems();
|
||||
|
||||
if (mActionDescription) mActionDescription->clear();
|
||||
|
||||
LLPanelGroupSubTab::setGroupID(id);
|
||||
}
|
||||
|
||||
// LLPanelGroupBanListSubTab /////////////////////////////////////////////
|
||||
// static
|
||||
void* LLPanelGroupBanListSubTab::createTab(void* data)
|
||||
{
|
||||
LLUUID* group_id = static_cast<LLUUID*>(data);
|
||||
return new LLPanelGroupBanListSubTab("panel group ban list sub tab", *group_id);
|
||||
}
|
||||
|
||||
LLPanelGroupBanListSubTab::LLPanelGroupBanListSubTab(const std::string& name, const LLUUID& group_id)
|
||||
: LLPanelGroupSubTab(name, group_id),
|
||||
mBanList(NULL),
|
||||
mCreateBanButton(NULL),
|
||||
mDeleteBanButton(NULL)
|
||||
{}
|
||||
|
||||
BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root)
|
||||
{
|
||||
LLPanelGroupSubTab::postBuildSubTab(root);
|
||||
|
||||
// Upcast parent so we can ask it for sibling controls.
|
||||
LLPanelGroupRoles* parent = (LLPanelGroupRoles*)root;
|
||||
|
||||
// Look recursively from the parent to find all our widgets.
|
||||
bool recurse = true;
|
||||
|
||||
mHeader = parent->getChild<LLPanel>("banlist_header", recurse);
|
||||
mFooter = parent->getChild<LLPanel>("banlist_footer", recurse);
|
||||
|
||||
mBanList = parent->getChild<LLNameListCtrl>("ban_list", recurse);
|
||||
|
||||
mCreateBanButton = parent->getChild<LLButton>("ban_create", recurse);
|
||||
mDeleteBanButton = parent->getChild<LLButton>("ban_delete", recurse);
|
||||
mRefreshBanListButton = parent->getChild<LLButton>("ban_refresh", recurse);
|
||||
|
||||
if (!mBanList || !mCreateBanButton || !mDeleteBanButton || !mRefreshBanListButton)
|
||||
return FALSE;
|
||||
|
||||
mBanList->setCommitOnSelectionChange(TRUE);
|
||||
mBanList->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleBanEntrySelect, this));
|
||||
|
||||
mCreateBanButton->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleCreateBanEntry, this));
|
||||
mCreateBanButton->setEnabled(FALSE);
|
||||
|
||||
mDeleteBanButton->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleDeleteBanEntry, this));
|
||||
mDeleteBanButton->setEnabled(FALSE);
|
||||
|
||||
mRefreshBanListButton->setCommitCallback(boost::bind(&LLPanelGroupBanListSubTab::handleRefreshBanList, this));
|
||||
mRefreshBanListButton->setEnabled(FALSE);
|
||||
|
||||
mBanList->setOnNameListCompleteCallback(boost::bind(&LLPanelGroupBanListSubTab::onBanListCompleted, this, _1));
|
||||
|
||||
populateBanList();
|
||||
|
||||
//setFooterEnabled(FALSE); // Singu Note: This probably serves no purpose upstream, but for us, we need the footer enabled because we use it to make use of this entire panel.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::activate()
|
||||
{
|
||||
LLPanelGroupSubTab::activate();
|
||||
|
||||
mBanList->deselectAllItems();
|
||||
mDeleteBanButton->setEnabled(FALSE);
|
||||
|
||||
mCreateBanButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS));
|
||||
|
||||
// BAKER: Should I really request everytime activate() is called?
|
||||
// Perhaps I should only do it on a force refresh, or if an action on the list happens...
|
||||
// Because it's not going to live-update the list anyway... You'd have to refresh if you
|
||||
// wanted to see someone else's additions anyway...
|
||||
//
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID);
|
||||
|
||||
//setFooterEnabled(FALSE); // Singu Note: This probably serves no purpose upstream, but for us, we need the footer enabled because we use it to make use of this entire panel.
|
||||
update(GC_ALL);
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::update(LLGroupChange gc)
|
||||
{
|
||||
populateBanList();
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::draw()
|
||||
{
|
||||
LLPanelGroupSubTab::draw();
|
||||
|
||||
// BAKER: Might be good to put it here instead of update, maybe.. See how often draw gets hit.
|
||||
//if(
|
||||
// populateBanList();
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::handleBanEntrySelect()
|
||||
{
|
||||
if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS))
|
||||
{
|
||||
mDeleteBanButton->setEnabled(!!mBanList->getFirstSelected()); // Singu Note: Avoid empty selection.
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::handleCreateBanEntry()
|
||||
{
|
||||
LLFloaterGroupBulkBan::showForGroup(mGroupID);
|
||||
//populateBanList();
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::handleDeleteBanEntry()
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
if (!gdatap)
|
||||
{
|
||||
LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Singu Note: We have this function, so there's less code here.
|
||||
uuid_vec_t ban_ids = mBanList->getSelectedIDs();
|
||||
if (ban_ids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool can_ban_members = false;
|
||||
if (gAgent.isGodlike() ||
|
||||
gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS))
|
||||
{
|
||||
can_ban_members = true;
|
||||
}
|
||||
|
||||
// Owners can ban anyone in the group.
|
||||
LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(gAgent.getID());
|
||||
if (mi != gdatap->mMembers.end())
|
||||
{
|
||||
LLGroupMemberData* member_data = (*mi).second;
|
||||
if (member_data && member_data->isInRole(gdatap->mOwnerRole))
|
||||
{
|
||||
can_ban_members = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!can_ban_members)
|
||||
return;
|
||||
|
||||
uuid_vec_t::iterator itor;
|
||||
for(itor = ban_ids.begin(); itor != ban_ids.end(); ++itor)
|
||||
{
|
||||
LLUUID ban_id = (*itor);
|
||||
|
||||
gdatap->removeBanEntry(ban_id);
|
||||
mBanList->removeNameItem(ban_id);
|
||||
|
||||
}
|
||||
// Removing an item removes the selection, we shouldn't be able to click the button anymore until we reselect another entry.
|
||||
mDeleteBanButton->setEnabled(FALSE);
|
||||
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_DELETE, ban_ids);
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::handleRefreshBanList()
|
||||
{
|
||||
mRefreshBanListButton->setEnabled(FALSE);
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID);
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::onBanListCompleted(bool isComplete)
|
||||
{
|
||||
if (isComplete)
|
||||
{
|
||||
mRefreshBanListButton->setEnabled(TRUE);
|
||||
populateBanList();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::populateBanList()
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
if (!gdatap)
|
||||
{
|
||||
LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
mBanList->deleteAllItems();
|
||||
std::map<LLUUID,LLGroupBanData>::const_iterator entry = gdatap->mBanList.begin();
|
||||
for(; entry != gdatap->mBanList.end(); entry++)
|
||||
{
|
||||
LLNameListCtrl::NameItem ban_entry;
|
||||
ban_entry.value = entry->first;
|
||||
LLGroupBanData bd = entry->second;
|
||||
|
||||
ban_entry.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL");
|
||||
|
||||
// Singu Note: We have special date columns, so our code is unique here
|
||||
ban_entry.columns.add().column("ban_date").value(bd.mBanDate).format("%Y/%m%d").font/*.name*/("SANSSERIF_SMALL").font_style("NORMAL");
|
||||
|
||||
mBanList->addNameItemRow(ban_entry);
|
||||
}
|
||||
|
||||
mRefreshBanListButton->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelGroupBanListSubTab::setGroupID(const LLUUID& id)
|
||||
{
|
||||
if (mBanList)
|
||||
mBanList->deleteAllItems();
|
||||
|
||||
//setFooterEnabled(FALSE);
|
||||
LLPanelGroupSubTab::setGroupID(id);
|
||||
}
|
||||
|
||||
@@ -46,11 +46,9 @@ class LLScrollListItem;
|
||||
class LLTextEditor;
|
||||
class LLGroupMemberData;
|
||||
|
||||
// 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 LLPanelGroupTabObserver
|
||||
{
|
||||
@@ -89,6 +87,8 @@ public:
|
||||
virtual void cancel();
|
||||
virtual void update(LLGroupChange gc);
|
||||
|
||||
virtual void setGroupID(const LLUUID& id);
|
||||
|
||||
// PanelGroupTab observer trigger
|
||||
virtual void tabChanged();
|
||||
|
||||
@@ -103,6 +103,7 @@ protected:
|
||||
std::string mWantApplyMesg;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupSubTab : public LLPanelGroupTab
|
||||
{
|
||||
public:
|
||||
@@ -123,6 +124,8 @@ public:
|
||||
bool matchesActionSearchFilter(std::string action);
|
||||
|
||||
void setFooterEnabled(BOOL enable);
|
||||
|
||||
virtual void setGroupID(const LLUUID& id);
|
||||
protected:
|
||||
void buildActionsList(LLScrollListCtrl* ctrl,
|
||||
U64 allowed_by_some,
|
||||
@@ -152,9 +155,13 @@ protected:
|
||||
|
||||
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:
|
||||
@@ -182,6 +189,9 @@ public:
|
||||
void handleRoleCheck(const LLUUID& role_id,
|
||||
LLRoleMemberChangeType type);
|
||||
|
||||
void handleBanMember();
|
||||
|
||||
|
||||
void applyMemberChanges();
|
||||
bool addOwnerCB(const LLSD& notification, const LLSD& response);
|
||||
|
||||
@@ -195,6 +205,8 @@ public:
|
||||
|
||||
virtual void draw();
|
||||
|
||||
virtual void setGroupID(const LLUUID& id);
|
||||
|
||||
void addMemberToList(LLGroupMemberData* data);
|
||||
void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id);
|
||||
|
||||
@@ -213,6 +225,7 @@ protected:
|
||||
LLScrollListCtrl* mAssignedRolesList;
|
||||
LLScrollListCtrl* mAllowedActionsList;
|
||||
LLButton* mEjectBtn;
|
||||
LLButton* mBanBtn;
|
||||
|
||||
BOOL mChanged;
|
||||
BOOL mPendingMemberUpdate;
|
||||
@@ -226,6 +239,7 @@ protected:
|
||||
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
|
||||
{
|
||||
public:
|
||||
@@ -266,6 +280,11 @@ public:
|
||||
void handleDeleteRole();
|
||||
|
||||
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);
|
||||
@@ -287,6 +306,7 @@ protected:
|
||||
std::string mRemoveEveryoneTxt;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab
|
||||
{
|
||||
public:
|
||||
@@ -304,6 +324,8 @@ public:
|
||||
virtual void update(LLGroupChange gc);
|
||||
|
||||
void handleActionSelect();
|
||||
|
||||
virtual void setGroupID(const LLUUID& id);
|
||||
protected:
|
||||
LLScrollListCtrl* mActionList;
|
||||
LLScrollListCtrl* mActionRoles;
|
||||
@@ -313,4 +335,42 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
class LLPanelGroupBanListSubTab : public LLPanelGroupSubTab
|
||||
{
|
||||
public:
|
||||
LLPanelGroupBanListSubTab(const std::string& name, const LLUUID& group_id);
|
||||
virtual ~LLPanelGroupBanListSubTab() {}
|
||||
|
||||
virtual BOOL postBuildSubTab(LLView* root);
|
||||
|
||||
static void* createTab(void* data);
|
||||
|
||||
virtual void activate();
|
||||
virtual void update(LLGroupChange gc);
|
||||
virtual void draw();
|
||||
|
||||
void handleBanEntrySelect();
|
||||
|
||||
void handleCreateBanEntry();
|
||||
|
||||
void handleDeleteBanEntry();
|
||||
|
||||
void handleRefreshBanList();
|
||||
|
||||
void onBanListCompleted(bool isComplete);
|
||||
|
||||
protected:
|
||||
void populateBanList();
|
||||
|
||||
public:
|
||||
virtual void setGroupID(const LLUUID& id);
|
||||
|
||||
protected:
|
||||
LLNameListCtrl* mBanList;
|
||||
LLButton* mCreateBanButton;
|
||||
LLButton* mDeleteBanButton;
|
||||
LLButton* mRefreshBanListButton;
|
||||
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELGROUPROLES_H
|
||||
|
||||
@@ -1719,6 +1719,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,7 +53,7 @@ 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)
|
||||
@@ -146,6 +146,9 @@ 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
|
||||
| GP_NOTICES_RECEIVE
|
||||
BIN
indra/newview/skins/default/textures/Refresh_Off.png
Normal file
BIN
indra/newview/skins/default/textures/Refresh_Off.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 483 B |
@@ -415,4 +415,5 @@
|
||||
<texture name="Inv_WindLight.png" preload="true"/>
|
||||
<texture name="Inv_WaterLight.png" preload="true"/>
|
||||
|
||||
<texture name="Refresh_Off" file_name="Refresh_Off.png" preload="true" />
|
||||
</textures>
|
||||
|
||||
@@ -612,6 +612,34 @@ Add this Ability to '[ROLE_NAME]'?
|
||||
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="AttachmentDrop"
|
||||
@@ -3333,6 +3361,28 @@ Leave Group?
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alert.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,86 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
height="270"
|
||||
label="Ban Residents"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="bulk_ban_panel"
|
||||
mouse_opaque="false"
|
||||
bottom="0"
|
||||
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="already_banned">
|
||||
Group Invitations not sent: resident '[RESIDENT]' already banned.
|
||||
</panel.string>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
height="54"
|
||||
bottom="-28"
|
||||
layout="topleft"
|
||||
left="7"
|
||||
name="help_text"
|
||||
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"
|
||||
bottom_delta="-10"
|
||||
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"
|
||||
menu_num="0"
|
||||
bottom_delta="-178"
|
||||
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"
|
||||
bottom_delta="-24"
|
||||
width="200" />
|
||||
<button
|
||||
height="20"
|
||||
label="Ban Residents"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="ban_button"
|
||||
bottom_delta="-26"
|
||||
width="135" />
|
||||
<button
|
||||
height="20"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
left_delta="137"
|
||||
name="cancel_button"
|
||||
bottom_delta="0"
|
||||
width="65" />
|
||||
<string
|
||||
name="GroupBulkBan">
|
||||
Group Ban
|
||||
</string>
|
||||
</panel>
|
||||
@@ -26,7 +26,7 @@ Resident Chooser' to start.
|
||||
tool_tip="Choose from the list of Roles you are allowed to assign members to."
|
||||
width="196" />
|
||||
<button bottom="4" font="SansSerifSmall" halign="center" height="20"
|
||||
label="Send Invitations" left="4" name="ok_button" width="130" />
|
||||
label="Send Invitations" left="4" name="invite_button" width="130" />
|
||||
<button bottom_delta="0" font="SansSerifSmall" halign="center" height="20"
|
||||
label="Cancel" left_delta="132" name="cancel_button" width="70" />
|
||||
<string name="confirm_invite_owner_str">
|
||||
@@ -39,7 +39,7 @@ Resident Chooser' to start.
|
||||
Group Invitations not sent: too many Residents selected. Group Invitations are limited to 100 per request.
|
||||
</string>
|
||||
<!--button bottom="25" font="SansSerifSmall" halign="center" height="20"
|
||||
label="Send Invitations" left="65" name="ok_button" width="140" />
|
||||
label="Send Invitations" left="65" name="invite_button" width="140" />
|
||||
<button bottom_delta="-22" font="SansSerifSmall" halign="center" height="20"
|
||||
label="Cancel" left_delta="0" name="cancel_button" width="140" /-->
|
||||
<string name="loading">(loading...)</string>
|
||||
|
||||
@@ -57,6 +57,18 @@ easily be customized, allowing for greater organization and flexibility.
|
||||
execute the Ability.
|
||||
</text>
|
||||
</panel>
|
||||
<panel border="false" bottom_delta="0" height="24" left="7" name="banlist_header"
|
||||
visible="false" width="380">
|
||||
<text bottom_delta="0" font="SansSerifBig" halign="left" height="16" left="0"
|
||||
name="static" width="200">
|
||||
Banned Residents
|
||||
</text>
|
||||
<text bottom_delta="-36" font="SansSerifSmall" halign="left" height="32" left="0"
|
||||
name="static2" width="394">
|
||||
Examine which Residents are not allowed in this group. Members with the
|
||||
'Manage ban list' ability may block certain residents from joining the group.
|
||||
</text>
|
||||
</panel>
|
||||
<tab_container border="false" bottom_delta="-190" height="180" left="6"
|
||||
name="roles_tab_container" tab_position="top" width="406">
|
||||
<panel border="true" bottom="0" height="164" label="Members" left="1"
|
||||
@@ -82,7 +94,8 @@ execute the Ability.
|
||||
<button bottom_delta="-20" font="SansSerif" halign="center" height="19"
|
||||
label="Invite New Member ..." left="4" name="member_invite" width="146" />
|
||||
<button bottom_delta="0" font="SansSerif" halign="center" height="19"
|
||||
label="Eject From Group" left="-153" name="member_eject" width="146" />
|
||||
label="Eject From Group" left_delta="149" name="member_eject" width="146" />
|
||||
<button bottom_delta="0" left_delta="149" width="100" follows="top|left" height="19" label="Ban Member(s)" name="member_ban"/>
|
||||
<string name="help_text">
|
||||
You can add or remove Roles assigned to Members.
|
||||
Select multiple Members by holding the Ctrl key and
|
||||
@@ -144,6 +157,21 @@ things in this group. There's a broad variety of Abilities.
|
||||
</string>
|
||||
<string name="power_folder_icon">inv_folder_plain_closed.tga</string>
|
||||
</panel>
|
||||
<panel
|
||||
border="false"
|
||||
height="303"
|
||||
label="Banned Residents"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
help_topic="roles_banlist_tab"
|
||||
name="banlist_sub_tab"
|
||||
width="310">
|
||||
<panel.string
|
||||
name="help_text">
|
||||
Any resident on the ban list will be unable to join the group.
|
||||
</panel.string>
|
||||
</panel>
|
||||
</tab_container>
|
||||
<panel border="false" bottom_delta="-235" height="215" left="7" name="members_footer"
|
||||
select="true" visible="true" width="406">
|
||||
@@ -265,4 +293,63 @@ things in this group. There's a broad variety of Abilities.
|
||||
height="125" left="150" multi_select="true" name="action_members"
|
||||
width="254" menu_num="0" name_system="GroupMembersNameSystem"/>
|
||||
</panel>
|
||||
<!-- Singu Note: This is a total hack, abusing that footer is not part of the tab container -->
|
||||
<panel border="false" bottom="-500" height="425" left="7" name="banlist_footer" mouse_opaque="false" visible="false">
|
||||
<name_list
|
||||
column_padding="0"
|
||||
draw_heading="true"
|
||||
height="368"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
right="-1"
|
||||
multi_select="true"
|
||||
name="ban_list"
|
||||
menu_num="0"
|
||||
name_system="GroupMembersNameSystem"
|
||||
bottom="-365">
|
||||
<column
|
||||
label="Resident"
|
||||
name="name"
|
||||
font_name="SANSSERIF_SMALL"
|
||||
font-style="NORMAL"
|
||||
relative_width="0.7" />
|
||||
<column
|
||||
label="Date Banned"
|
||||
name="ban_date"
|
||||
relative_width="0.3" />
|
||||
</name_list>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="20"
|
||||
label="Ban Resident(s)"
|
||||
layout="topleft"
|
||||
left="3"
|
||||
name="ban_create"
|
||||
tool_tip="Ban residents from your group"
|
||||
width="120" />
|
||||
<button
|
||||
follows="top|left"
|
||||
bottom_delta="0"
|
||||
height="20"
|
||||
label="Remove Ban(s)"
|
||||
layout="topleft"
|
||||
left_delta="125"
|
||||
name="ban_delete"
|
||||
tool_tip="Unban selected residents from your group"
|
||||
width="120" />
|
||||
<button
|
||||
follows="top|left"
|
||||
bottom_delta="0"
|
||||
height="20"
|
||||
width="100"
|
||||
image_overlay="Refresh_Off"
|
||||
image_overlay_alignment="left"
|
||||
layout="topleft"
|
||||
left_delta="165"
|
||||
name="ban_refresh"
|
||||
label="Refresh"
|
||||
tool_tip="Refresh the ban list"
|
||||
/>
|
||||
</panel>
|
||||
</panel>
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
<action description="Eject Members from this Group"
|
||||
longdescription="Eject Members from this Group using the 'Eject From Group' button in the Members & Roles tab > Members sub-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 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 'Signup Fee'"
|
||||
longdescription="Toggle 'Open Enrollment' to let new Members join without an invitation, and change 'Signup Fee' in the Group Preferences section of the General tab."
|
||||
|
||||
Reference in New Issue
Block a user