diff options
| author | Baker Linden <baker@lindenlab.com> | 2013-08-29 11:36:45 -0700 | 
|---|---|---|
| committer | Baker Linden <baker@lindenlab.com> | 2013-08-29 11:36:45 -0700 | 
| commit | 4945ae17d3692f089ce6c996f6585a5e5b308e4d (patch) | |
| tree | ca50d30f551659a790c4f4327b0767dae844c7be | |
| parent | 6060e5e46acbeb20a301070a0fd0efea029d33d0 (diff) | |
Initial commit for GroupBan
- Lots of crap isn't working as intended yet.
22 files changed, 2072 insertions, 673 deletions
| diff --git a/indra/llcommon/roles_constants.h b/indra/llcommon/roles_constants.h index effd15ea72..ee3e8b6b74 100755 --- a/indra/llcommon/roles_constants.h +++ b/indra/llcommon/roles_constants.h @@ -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 << 50 and above  // These powers were removed to make group roles simpler  // bit 0x1 << 41 (GP_ACCOUNTING_VIEW) @@ -63,88 +63,90 @@ const U64 GP_NO_POWERS = 0x0;  const U64 GP_ALL_POWERS = 0xFFFFFFFFFFFFFFFFLL;  // Membership -const U64 GP_MEMBER_INVITE		= 0x1 << 1;		// Invite member -const U64 GP_MEMBER_EJECT			= 0x1 << 2;		// Eject member from group -const U64 GP_MEMBER_OPTIONS		= 0x1 << 3;		// Toggle "Open enrollment" and change "Signup Fee" -const U64 GP_MEMBER_VISIBLE_IN_DIR = 0x1LL << 47; +const U64 GP_MEMBER_INVITE				= 0x1LL << 1;	// Invite member +const U64 GP_MEMBER_EJECT				= 0x1LL << 2;	// Eject member from group +const U64 GP_MEMBER_OPTIONS				= 0x1LL << 3;	// Toggle "Open enrollment" and change "Signup Fee" +const U64 GP_MEMBER_VISIBLE_IN_DIR		= 0x1LL << 47;  // Roles -const U64 GP_ROLE_CREATE			= 0x1 << 4;		// Create new roles -const U64 GP_ROLE_DELETE			= 0x1 << 5;		// Delete roles -const U64 GP_ROLE_PROPERTIES		= 0x1 << 6;		// Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?) -const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED = 0x1 << 7; // Assign Member to a Role that the assigner is in -const U64 GP_ROLE_ASSIGN_MEMBER	= 0x1 << 8;		// Assign Member to Role -const U64 GP_ROLE_REMOVE_MEMBER	= 0x1 << 9;		// Remove Member from Role -const U64 GP_ROLE_CHANGE_ACTIONS	= 0x1 << 10;	// Change actions a role can perform +const U64 GP_ROLE_CREATE				= 0x1LL << 4;	// Create new roles +const U64 GP_ROLE_DELETE				= 0x1LL << 5;	// Delete roles +const U64 GP_ROLE_PROPERTIES			= 0x1LL << 6;	// Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?) +const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED	= 0x1LL << 7;	// Assign Member to a Role that the assigner is in +const U64 GP_ROLE_ASSIGN_MEMBER			= 0x1LL << 8;	// Assign Member to Role +const U64 GP_ROLE_REMOVE_MEMBER			= 0x1LL << 9;	// Remove Member from Role +const U64 GP_ROLE_CHANGE_ACTIONS		= 0x1LL << 10;	// Change actions a role can perform  // Group Identity -const U64 GP_GROUP_CHANGE_IDENTITY = 0x1 << 11;	// Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes +const U64 GP_GROUP_CHANGE_IDENTITY		= 0x1LL << 11;	// Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes  // Parcel Management -const U64 GP_LAND_DEED			= 0x1 << 12;	// Deed Land and Buy Land for Group -const U64 GP_LAND_RELEASE			= 0x1 << 13;	// Release Land (to Gov. Linden) -const U64 GP_LAND_SET_SALE_INFO	= 0x1 << 14;	// Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land") -const U64 GP_LAND_DIVIDE_JOIN		= 0x1 << 15;	// Divide and Join Parcels +const U64 GP_LAND_DEED					= 0x1LL << 12;	// Deed Land and Buy Land for Group +const U64 GP_LAND_RELEASE				= 0x1LL << 13;	// Release Land (to Gov. Linden) +const U64 GP_LAND_SET_SALE_INFO			= 0x1LL << 14;	// Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land") +const U64 GP_LAND_DIVIDE_JOIN			= 0x1LL << 15;	// Divide and Join Parcels  // Parcel Identity -const U64 GP_LAND_FIND_PLACES		= 0x1 << 17;	// Toggle "Show in Find Places" and Set Category. -const U64 GP_LAND_CHANGE_IDENTITY = 0x1 << 18;	// Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox -const U64 GP_LAND_SET_LANDING_POINT = 0x1 << 19;	// Set Landing Point +const U64 GP_LAND_FIND_PLACES			= 0x1LL << 17;	// Toggle "Show in Find Places" and Set Category. +const U64 GP_LAND_CHANGE_IDENTITY		= 0x1LL << 18;	// Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox +const U64 GP_LAND_SET_LANDING_POINT		= 0x1LL << 19;	// Set Landing Point  // Parcel Settings -const U64 GP_LAND_CHANGE_MEDIA	= 0x1 << 20;	// Change Media Settings -const U64 GP_LAND_EDIT			= 0x1 << 21;	// Toggle Edit Land -const U64 GP_LAND_OPTIONS			= 0x1 << 22;	// Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes +const U64 GP_LAND_CHANGE_MEDIA			= 0x1LL << 20;	// Change Media Settings +const U64 GP_LAND_EDIT					= 0x1LL << 21;	// Toggle Edit Land +const U64 GP_LAND_OPTIONS				= 0x1LL << 22;	// Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes  // Parcel Powers -const U64 GP_LAND_ALLOW_EDIT_LAND = 0x1 << 23;	// Bypass Edit Land Restriction -const U64 GP_LAND_ALLOW_FLY		= 0x1 << 24;	// Bypass Fly Restriction -const U64 GP_LAND_ALLOW_CREATE	= 0x1 << 25;	// Bypass Create/Edit Objects Restriction -const U64 GP_LAND_ALLOW_LANDMARK	= 0x1 << 26;	// Bypass Landmark Restriction -const U64 GP_LAND_ALLOW_SET_HOME	= 0x1 << 28;	// Bypass Set Home Point Restriction -const U64 GP_LAND_ALLOW_HOLD_EVENT	= 0x1LL << 41;	// Allowed to hold events on group-owned land - +const U64 GP_LAND_ALLOW_EDIT_LAND		= 0x1LL << 23;	// Bypass Edit Land Restriction +const U64 GP_LAND_ALLOW_FLY				= 0x1LL << 24;	// Bypass Fly Restriction +const U64 GP_LAND_ALLOW_CREATE			= 0x1LL << 25;	// Bypass Create/Edit Objects Restriction +const U64 GP_LAND_ALLOW_LANDMARK		= 0x1LL << 26;	// Bypass Landmark Restriction +const U64 GP_LAND_ALLOW_SET_HOME		= 0x1LL << 28;	// Bypass Set Home Point Restriction +const U64 GP_LAND_ALLOW_HOLD_EVENT		= 0x1LL << 41;	// Allowed to hold events on group-owned land  // Parcel Access -const U64 GP_LAND_MANAGE_ALLOWED	= 0x1 << 29;	// Manage Allowed List -const U64 GP_LAND_MANAGE_BANNED	= 0x1 << 30;	// Manage Banned List -const U64 GP_LAND_MANAGE_PASSES	= 0x1LL << 31;	// Change Sell Pass Settings -const U64 GP_LAND_ADMIN			= 0x1LL << 32;	// Eject and Freeze Users on the land +const U64 GP_LAND_MANAGE_ALLOWED		= 0x1LL << 29;	// Manage Allowed List +const U64 GP_LAND_MANAGE_BANNED			= 0x1LL << 30;	// Manage Banned List +const U64 GP_LAND_MANAGE_PASSES			= 0x1LL << 31;	// Change Sell Pass Settings +const U64 GP_LAND_ADMIN					= 0x1LL << 32;	// Eject and Freeze Users on the land  // Parcel Content -const U64 GP_LAND_RETURN_GROUP_SET	= 0x1LL << 33;	// Return objects on parcel that are set to group -const U64 GP_LAND_RETURN_NON_GROUP	= 0x1LL << 34;	// Return objects on parcel that are not set to group -const U64 GP_LAND_RETURN_GROUP_OWNED= 0x1LL << 48;	// Return objects on parcel that are owned by the group +const U64 GP_LAND_RETURN_GROUP_SET		= 0x1LL << 33;	// Return objects on parcel that are set to group +const U64 GP_LAND_RETURN_NON_GROUP		= 0x1LL << 34;	// Return objects on parcel that are not set to group +const U64 GP_LAND_RETURN_GROUP_OWNED	= 0x1LL << 48;	// Return objects on parcel that are owned by the group  // Select a power-bit based on an object's relationship to a parcel.  const U64 GP_LAND_RETURN		= GP_LAND_RETURN_GROUP_OWNED   								| GP_LAND_RETURN_GROUP_SET	  								| GP_LAND_RETURN_NON_GROUP; -const U64 GP_LAND_GARDENING		= 0x1LL << 35;	// Parcel Gardening - plant and move linden trees +const U64 GP_LAND_GARDENING				= 0x1LL << 35;	// Parcel Gardening - plant and move linden trees  // Object Management -const U64 GP_OBJECT_DEED			= 0x1LL << 36;	// Deed Object -const U64 GP_OBJECT_MANIPULATE		= 0x1LL << 38;	// Manipulate Group Owned Objects (Move, Copy, Mod) -const U64 GP_OBJECT_SET_SALE		= 0x1LL << 39;	// Set Group Owned Object for Sale +const U64 GP_OBJECT_DEED				= 0x1LL << 36;	// Deed Object +const U64 GP_OBJECT_MANIPULATE			= 0x1LL << 38;	// Manipulate Group Owned Objects (Move, Copy, Mod) +const U64 GP_OBJECT_SET_SALE			= 0x1LL << 39;	// Set Group Owned Object for Sale  // Accounting -const U64 GP_ACCOUNTING_ACCOUNTABLE = 0x1LL << 40;	// Pay Group Liabilities and Receive Group Dividends +const U64 GP_ACCOUNTING_ACCOUNTABLE		= 0x1LL << 40;	// Pay Group Liabilities and Receive Group Dividends  // Notices -const U64 GP_NOTICES_SEND			= 0x1LL << 42;	// Send Notices -const U64 GP_NOTICES_RECEIVE		= 0x1LL << 43;	// Receive Notices and View Notice History +const U64 GP_NOTICES_SEND				= 0x1LL << 42;	// Send Notices +const U64 GP_NOTICES_RECEIVE			= 0x1LL << 43;	// Receive Notices and View Notice History  // Proposals  // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: -const U64 GP_PROPOSAL_START		= 0x1LL << 44;	// Start Proposal +const U64 GP_PROPOSAL_START				= 0x1LL << 44;	// Start Proposal  // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: -const U64 GP_PROPOSAL_VOTE		= 0x1LL << 45;	// Vote on Proposal +const U64 GP_PROPOSAL_VOTE				= 0x1LL << 45;	// Vote on Proposal  // Group chat moderation related -const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session -const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk -const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session +const U64 GP_SESSION_JOIN				= 0x1LL << 16;	//can join session +const U64 GP_SESSION_VOICE				= 0x1LL << 27;	//can hear/talk +const U64 GP_SESSION_MODERATOR			= 0x1LL << 37;	//can mute people's session + +// Group Banning +const U64 GP_GROUP_BAN_ACCESS			= 0x1LL << 49;	// Allows access to ban / un-ban agents from a group.  const U64 GP_DEFAULT_MEMBER = GP_ACCOUNTING_ACCOUNTABLE  								| GP_LAND_ALLOW_SET_HOME diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index efcbe76795..b505ef0b4b 100755 --- a/indra/llcommon/stdenums.h +++ b/indra/llcommon/stdenums.h @@ -127,6 +127,7 @@ enum LLGroupChange  	GC_ROLE_DATA,  	GC_ROLE_MEMBER_DATA,  	GC_TITLES, +	GC_BANLIST,  	GC_ALL  }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d06cee5ee6..6a9f91ffcd 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -229,6 +229,7 @@ set(viewer_SOURCE_FILES      llfloaterfonttest.cpp      llfloatergesture.cpp      llfloatergodtools.cpp +    llfloatergroupbulkban.cpp      llfloatergroupinvite.cpp      llfloatergroups.cpp      llfloaterhandler.cpp @@ -398,6 +399,8 @@ set(viewer_SOURCE_FILES      llpanelface.cpp      llpanelgenerictip.cpp      llpanelgroup.cpp +    llpanelgroupbulk.cpp +    llpanelgroupbulkban.cpp      llpanelgroupgeneral.cpp      llpanelgroupinvite.cpp      llpanelgrouplandmoney.cpp @@ -812,6 +815,7 @@ set(viewer_HEADER_FILES      llfloaterfonttest.h      llfloatergesture.h      llfloatergodtools.h +    llfloatergroupbulkban.h      llfloatergroupinvite.h      llfloatergroups.h      llfloaterhandler.h @@ -974,6 +978,9 @@ set(viewer_HEADER_FILES      llpanelface.h      llpanelgenerictip.h      llpanelgroup.h +    llpanelgroupbulk.h +    llpanelgroupbulkimpl.h +    llpanelgroupbulkban.h      llpanelgroupgeneral.h      llpanelgroupinvite.h      llpanelgrouplandmoney.h diff --git a/indra/newview/llfloatergroupbulkban.cpp b/indra/newview/llfloatergroupbulkban.cpp new file mode 100644 index 0000000000..54a2283b13 --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.cpp @@ -0,0 +1,134 @@ +/**  +* @file llfloatergroupbulkban.cpp +* @brief Floater to ban Residents from a group. +*  +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatergroupbulkban.h" +#include "llpanelgroupbulkban.h" +#include "lltrans.h" +#include "lldraghandle.h" + + +class LLFloaterGroupBulkBan::impl +{ +public: +	impl(const LLUUID& group_id) : mGroupID(group_id), mBulkBanPanelp(NULL) {} +	~impl() {} + +	static void closeFloater(void* data); + +public: +	LLUUID mGroupID; +	LLPanelGroupBulkBan* mBulkBanPanelp; + +	static std::map<LLUUID, LLFloaterGroupBulkBan*> sInstances; +}; + +// +// Globals +// +std::map<LLUUID, LLFloaterGroupBulkBan*> LLFloaterGroupBulkBan::impl::sInstances; + +void LLFloaterGroupBulkBan::impl::closeFloater(void* data) +{ +	LLFloaterGroupBulkBan* floaterp = (LLFloaterGroupBulkBan*)data; +	if(floaterp) +		floaterp->closeFloater(); +} + +//----------------------------------------------------------------------------- +// Implementation +//----------------------------------------------------------------------------- +LLFloaterGroupBulkBan::LLFloaterGroupBulkBan(const LLUUID& group_id/*=LLUUID::null*/) +	: LLFloater(group_id) +{ +	S32 floater_header_size = getHeaderHeight(); +	LLRect contents; + +	mImpl = new impl(group_id); +	mImpl->mBulkBanPanelp = new LLPanelGroupBulkBan(group_id); + +	contents = mImpl->mBulkBanPanelp->getRect(); +	contents.mTop -= floater_header_size; + +	setTitle(mImpl->mBulkBanPanelp->getString("GroupBulkBan")); +	mImpl->mBulkBanPanelp->setCloseCallback(impl::closeFloater, this); +	mImpl->mBulkBanPanelp->setRect(contents); + +	addChild(mImpl->mBulkBanPanelp); +} + +LLFloaterGroupBulkBan::~LLFloaterGroupBulkBan() +{ +	if(mImpl->mGroupID.notNull()) +	{ +		impl::sInstances.erase(mImpl->mGroupID); +	} + +	delete mImpl->mBulkBanPanelp; +	delete mImpl; +} + +void LLFloaterGroupBulkBan::showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids) +{ +	const LLFloater::Params& floater_params = LLFloater::getDefaultParams(); +	S32 floater_header_size = floater_params.header_height; +	LLRect contents; + +	// Make sure group_id isn't null +	if (group_id.isNull()) +	{ +		llwarns << "LLFloaterGroupInvite::showForGroup with null group_id!" << llendl; +		return; +	} + +	// If we don't have a floater for this group, create one. +	LLFloaterGroupBulkBan* fgb = get_if_there(impl::sInstances, +		group_id, +		(LLFloaterGroupBulkBan*)NULL); +	if (!fgb) +	{ +		fgb = new LLFloaterGroupBulkBan(group_id); +		contents = fgb->mImpl->mBulkBanPanelp->getRect(); +		contents.mTop += floater_header_size; +		fgb->setRect(contents); +		fgb->getDragHandle()->setRect(contents); +		fgb->getDragHandle()->setTitle(fgb->mImpl->mBulkBanPanelp->getString("GroupBulkBan")); + +		impl::sInstances[group_id] = fgb; + +		fgb->mImpl->mBulkBanPanelp->clear(); +	} + +	if (agent_ids != NULL) +	{ +		fgb->mImpl->mBulkBanPanelp->addUsers(*agent_ids); +	} + +	fgb->center(); +	fgb->openFloater(); +	fgb->mImpl->mBulkBanPanelp->update(); +} diff --git a/indra/newview/llfloatergroupbulkban.h b/indra/newview/llfloatergroupbulkban.h new file mode 100644 index 0000000000..5b680a1ba4 --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.h @@ -0,0 +1,48 @@ +/**  +* @file   llfloatergroupbulkban.h +* @brief  This floater is a wrapper for LLPanelGroupBulkBan, which +* is used to ban Residents from a specific group. +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLFLOATERGROUPBULKBAN_H +#define LL_LLFLOATERGROUPBULKBAN_H + +#include "llfloater.h" +#include "lluuid.h" + +class LLFloaterGroupBulkBan : public LLFloater +{ +public: +	virtual ~LLFloaterGroupBulkBan(); + +	static void showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids = NULL); + +protected: +	LLFloaterGroupBulkBan(const LLUUID& group_id = LLUUID::null); + +	class impl; +	impl* mImpl; +}; + +#endif // LL_LLFLOATERGROUPBULKBAN_H diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index cbd844cdac..0d4b678019 100755 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -231,11 +231,13 @@ 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), +	mGroupBanStatus(STATUS_INIT), +	mGroupBanDataComplete(false), +	mPendingRoleMemberRequest(false),  	mAccessTime(0.0f)  {  	mMemberVersion.generate(); @@ -424,7 +426,7 @@ void LLGroupMgrGroupData::removeMemberData()  		delete mi->second;  	}  	mMembers.clear(); -	mMemberDataComplete = FALSE; +	mMemberDataComplete = false;  	mMemberVersion.generate();  } @@ -446,8 +448,8 @@ void LLGroupMgrGroupData::removeRoleData()  	}  	mRoles.clear();  	mReceivedRoleMemberPairs = 0; -	mRoleDataComplete = FALSE; -	mRoleMemberDataComplete = FALSE; +	mRoleDataComplete = false; +	mRoleMemberDataComplete= false;  }  void LLGroupMgrGroupData::removeRoleMemberData() @@ -471,7 +473,7 @@ void LLGroupMgrGroupData::removeRoleMemberData()  	}  	mReceivedRoleMemberPairs = 0; -	mRoleMemberDataComplete = FALSE; +	mRoleMemberDataComplete= false;  }  LLGroupMgrGroupData::~LLGroupMgrGroupData() @@ -742,6 +744,22 @@ 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; +} + +bool LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id) +{ +	// Once we get this hooked up to the backend, we want to confirm the create or delete worked. +	mBanList.erase(ban_id); +	return true; +} + + + +  //  // LLGroupMgr  // @@ -951,12 +969,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);  		}  	} @@ -1026,7 +1044,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); @@ -1103,12 +1121,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);  		}  	} @@ -1217,7 +1235,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)  			}  		} -        group_datap->mRoleMemberDataComplete = TRUE; +        group_datap->mRoleMemberDataComplete= true;  		group_datap->mRoleMembersRequestID.setNull();  	} @@ -1543,7 +1561,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)  			llinfos << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N")  				<< " MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N")  				<< " RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << llendl; -			group_datap->mPendingRoleMemberRequest = TRUE; +			group_datap->mPendingRoleMemberRequest = true;  			return;  		} @@ -1841,6 +1859,122 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,  // Responder class for capability group management +class GroupBanDataResponder : public LLHTTPClient::Responder +{ +public: +	GroupBanDataResponder() {} +	virtual ~GroupBanDataResponder() {} +	virtual void result(const LLSD& pContent); +	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent); +}; + +void GroupBanDataResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent) +{ +	LL_WARNS("GrpMgr") << "Error receiving group member data [status:"  +		<< pStatus << "]: " << pContent << LL_ENDL; +} + +void GroupBanDataResponder::result(const LLSD& content) +{ +	LL_INFOS("GrpMgr") << "[BAKER] Received ban data!" << LL_ENDL; +	LLGroupMgr::processGroupBanRequest(content); +} + +void LLGroupMgr::sendGroupBanRequest(EBanRequestType request_type, const LLUUID& group_id, 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("GroupBan"); +	if(cap_url.empty()) +	{ +		return; +	} + +	LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(); +	// PUT to our service.  Add a body containing the group_id and list of agents to ban. +	LLSD ban_ids = LLSD::emptyMap(); +	ban_ids["group_id"] = group_id; +	// Add our list of potential banned agents to the list +	ban_ids["ban_ids"]	= LLSD::emptyArray(); +	LLSD ban_entry; +	std::vector<LLUUID>::const_iterator iter = ban_list.cbegin(); +	for(;iter != ban_list.end(); ++iter) +	{ +		ban_entry = (*iter); +		ban_ids["ban_ids"].append(ban_entry); +	} + +	switch(request_type) +	{ +	case REQUEST_GET: +		cap_url += "?group_id=" + group_id.asString(); +		LLHTTPClient::get(cap_url, grp_ban_responder); +		break; +	case REQUEST_PUT: +		// BAKER TODO: Figure out which 'body' is correct. +		LLHTTPClient::put(cap_url, ban_ids, grp_ban_responder, LLSD(), 60); +		break; +	case REQUEST_DEL: +		LLHTTPClient::del(cap_url, grp_ban_responder, ban_ids, 60); +		break; +	} + +	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); +	if (gdatap) +		gdatap->setGroupBanStatus(LLGroupMgrGroupData::STATUS_REQUESTING); +} + + +void LLGroupMgr::processGroupBanRequest(const LLSD& content) +{ +	// Did we get anything in content? +	if(!content.size()) +	{ +		LL_DEBUGS("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 banlist = LLSD::emptyMap(); + + +	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); +		// We have nothing right now inside our banlist map. +		// Once ban_date is implemented, set that here! +		//  +		gdatap->createBanEntry(ban_id, LLGroupBanData()); +	} + +	gdatap->mChanged = TRUE; +	gdatap->setGroupBanStatus(LLGroupMgrGroupData::STATUS_COMPLETE); +	LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST); +} + + + +// Responder class for capability group management  class GroupMemberDataResponder : public LLHTTPClient::Responder  {  public: @@ -1925,7 +2059,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)  	if(num_members < 1)  		return; -	LLUUID	group_id = content["group_id"].asUUID(); +	LLUUID group_id = content["group_id"].asUUID();  	LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);  	if(!group_datap) @@ -2008,12 +2142,12 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)  		LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); -	group_datap->mMemberDataComplete = TRUE; +	group_datap->mMemberDataComplete = true;  	group_datap->mMemberRequestID.setNull();  	// Make the role-member data request  	if (group_datap->mPendingRoleMemberRequest)  	{ -		group_datap->mPendingRoleMemberRequest = FALSE; +		group_datap->mPendingRoleMemberRequest = false;  		LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);  	} diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index d8c1ab7ef5..876883e87e 100755 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -33,7 +33,11 @@  #include <string>  #include <map> +// Forward Declarations  class LLMessageSystem; +class LLGroupRoleData; +class LLGroupMgr; +  class LLGroupMgrObserver  { @@ -54,8 +58,6 @@ public:  	virtual void changed(const LLUUID& group_id, LLGroupChange gc) = 0;  }; -class LLGroupRoleData; -  class LLGroupMemberData  {  friend class LLGroupMgrGroupData; @@ -190,6 +192,16 @@ struct lluuid_pair_less  	}  }; + +struct LLGroupBanData +{ +	LLGroupBanData()	{ mBanDate = "00/00/0000"; } +	~LLGroupBanData()	{} +	 +	std::string mBanDate; // Just store something here to ensure it works. +}; + +  struct LLGroupTitle  {  	std::string mTitle; @@ -197,11 +209,17 @@ struct LLGroupTitle  	BOOL		mSelected;  }; -class LLGroupMgr; -  class LLGroupMgrGroupData  {  friend class LLGroupMgr; +public: +	enum EGroupDataStatus +	{ +		STATUS_NONE, +		STATUS_REQUESTING, +		STATUS_COMPLETE +	}; +  public:  	LLGroupMgrGroupData(const LLUUID& id); @@ -228,27 +246,46 @@ public:  	void recalcAllAgentPowers();  	void recalcAgentPowers(const LLUUID& agent_id); -	BOOL isMemberDataComplete() { return mMemberDataComplete; } -	BOOL isRoleDataComplete() { return mRoleDataComplete; } -	BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; } -	BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } +	bool isMemberDataComplete() { return mMemberDataComplete; } +	bool isRoleDataComplete() { return mRoleDataComplete; } +	bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; } +	bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } +	bool isGroupBanDataComplete() { return mGroupBanDataComplete; } +	 +	EGroupDataStatus getGroupBanStatus() { return mGroupBanStatus; } +	void setGroupBanStatus(EGroupDataStatus status) { mGroupBanStatus = status; }  	F32 getAccessTime() const { return mAccessTime; }  	void setAccessed();  	const LLUUID& getMemberVersion() const { return mMemberVersion; } +	////////////////////////////////////////////////////////////////////////// +	// BAN LIST +	////////////////////////////////////////////////////////////////////////// +	void clearBanList() { mBanList.clear(); } + +	void getBanList(const LLUUID& group_id, LLGroupBanData& ban_data); +	const LLGroupBanData& getBanEntry(const LLUUID& ban_id) { return mBanList[ban_id]; } +	 +	void createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data = LLGroupBanData()); +	bool 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; @@ -279,12 +316,16 @@ private:  	LLUUID				mTitlesRequestID;  	U32					mReceivedRoleMemberPairs; -	BOOL				mMemberDataComplete; -	BOOL				mRoleDataComplete; -	BOOL				mRoleMemberDataComplete; -	BOOL				mGroupPropertiesDataComplete; +	bool				mMemberDataComplete; +	bool				mRoleDataComplete; +	bool				mRoleMemberDataComplete; +	bool				mGroupPropertiesDataComplete; +	 +	EGroupDataStatus	mGroupBanStatus; +	bool				mGroupBanDataComplete; +	bool				mGroupBanDataPending; -	BOOL				mPendingRoleMemberRequest; +	bool				mPendingRoleMemberRequest;  	F32					mAccessTime;  	// Generate a new ID every time mMembers @@ -312,6 +353,14 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>  	LOG_CLASS(LLGroupMgr);  public: +	enum EBanRequestType +	{ +		REQUEST_GET = 0, +		REQUEST_PUT, +		REQUEST_DEL +	}; + +public:  	LLGroupMgr();  	~LLGroupMgr(); @@ -344,6 +393,9 @@ public:  	static void sendGroupMemberInvites(const LLUUID& group_id, std::map<LLUUID,LLUUID>& role_member_pairs);  	static void sendGroupMemberEjects(const LLUUID& group_id,  									  uuid_vec_t& member_ids); +	// BAKER - Group Ban +	static void sendGroupBanRequest(EBanRequestType request_type, const LLUUID& group_id, const std::vector<LLUUID> ban_list = std::vector<LLUUID>()); +	static void processGroupBanRequest(const LLSD& content);  	// BAKER  	void sendCapGroupMembersRequest(const LLUUID& group_id); @@ -390,4 +442,3 @@ private:  #endif - diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp new file mode 100644 index 0000000000..6c6fd8cfe0 --- /dev/null +++ b/indra/newview/llpanelgroupbulk.cpp @@ -0,0 +1,403 @@ +/**  +* @file llpanelgroupbulk.cpp +* @brief Implementation of llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h" + +#include "llagent.h" +#include "llavatarnamecache.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcallingcard.h" +#include "llcombobox.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + + +////////////////////////////////////////////////////////////////////////// +// Implementation of llpanelgroupbulkimpl.h functions +////////////////////////////////////////////////////////////////////////// +LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : +	mGroupID(group_id), +	mBulkAgentList(NULL), +	mOKButton(NULL), +	mRemoveButton(NULL), +	mGroupName(NULL), +	mLoadingText(), +	mTooManySelected(), +	mCloseCallback(NULL), +	mCloseCallbackUserData(NULL), +	mAvatarNameCacheConnection(), +	mRoleNames(NULL), +	mOwnerWarning(), +	mAlreadyInGroup(), +	mConfirmedOwnerInvite(false) +{} + +LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() +{ +	if(mAvatarNameCacheConnection.connected()) +	{ +		mAvatarNameCacheConnection.disconnect(); +	} +} + +void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata) +{ +	LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata; + +	if(panelp) +	{ +		//Right now this is hard coded with some knowledge that it is part +		//of a floater since the avatar picker needs to be added as a dependent +		//floater to the parent floater. +		//Soon the avatar picker will be embedded into this panel +		//instead of being it's own separate floater.  But that is next week. +		//This will do for now. -jwolk May 10, 2006 +		LLView* button = panelp->findChild<LLButton>("add_button"); +		LLFloater* root_floater = gFloaterView->getParentFloater(panelp); +		LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( +			boost::bind(callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button); +		if(picker) +		{ +			root_floater->addDependentFloater(picker); +		} +	} +} + +void LLPanelGroupBulkImpl::callbackClickRemove(void* userdata) +{ +	LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; +	if (selfp)  +		selfp->handleRemove(); +} + +void LLPanelGroupBulkImpl::callbackClickCancel(void* userdata) +{ +	LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; +	if(selfp)  +		(*(selfp->mCloseCallback))(selfp->mCloseCallbackUserData); +} + +void LLPanelGroupBulkImpl::callbackSelect(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; +	if (selfp)  +		selfp->handleSelection(); +} + +void LLPanelGroupBulkImpl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data) +{ +	std::vector<std::string> names; +	for (S32 i = 0; i < (S32)agent_ids.size(); i++) +	{ +		LLAvatarName av_name; +		if (LLAvatarNameCache::get(agent_ids[i], &av_name)) +		{ +			onAvatarNameCache(agent_ids[i], av_name, user_data); +		} +		else  +		{ +			LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data; +			if (selfp) +			{ +				if (selfp->mAvatarNameCacheConnection.connected()) +				{ +					selfp->mAvatarNameCacheConnection.disconnect(); +				} +				// *TODO : Add a callback per avatar name being fetched. +				selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(onAvatarNameCache, _1, _2, user_data)); +			} +		} +	} +} + +void LLPanelGroupBulkImpl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data) +{ +	LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data; + +	if (selfp) +	{ +		if (selfp->mAvatarNameCacheConnection.connected()) +		{ +			selfp->mAvatarNameCacheConnection.disconnect(); +		} +		std::vector<std::string> names; +		uuid_vec_t agent_ids; +		agent_ids.push_back(agent_id); +		names.push_back(av_name.getCompleteName()); + +		selfp->addUsers(names, agent_ids); +	} +} + +void LLPanelGroupBulkImpl::handleRemove() +{ +	std::vector<LLScrollListItem*> selection = mBulkAgentList->getAllSelected(); +	if (selection.empty())  +		return; + +	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; + +	for (S32 i = 0; i < (S32)names.size(); ++i) +	{ +		name = names[i]; +		id = agent_ids[i]; + +		// Make sure this agent isn't already in the list. +		bool already_in_list = false; +		std::vector<LLScrollListItem*> items = mBulkAgentList->getAllData(); +		std::vector<LLScrollListItem*>::iterator iter = items.begin(); +		for (; iter != items.end(); ++iter) +		{ +			LLScrollListItem* item = *iter; +			if (item->getUUID() == id) +			{ +				already_in_list = true; +				break; +			} +		} +		if (already_in_list) +		{ +			continue; +		} + +		//add the name to the names list +		LLSD row; +		row["id"] = id; +		row["columns"][0]["value"] = name; + +		mBulkAgentList->addElement(row); +		 +		// 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() +{ +	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) +		return; + +	if(gdatap->isGroupPropertiesDataComplete()) +		mPendingGroupPropertiesUpdate = false; +	else +	{ +		if(!mPendingGroupPropertiesUpdate) +		{ +			mPendingGroupPropertiesUpdate = true; +			LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); +		} +	} + +	if(gdatap->isRoleDataComplete()) +		mPendingRoleDataUpdate = false; +	else +	{ +		if(!mPendingRoleDataUpdate) +		{ +			mPendingRoleDataUpdate = true; +			LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); +		} +	} + +	if(gdatap->isMemberDataComplete()) +		mPendingMemberDataUpdate = false; +	else +	{ +		if(!mPendingMemberDataUpdate) +		{ +			mPendingMemberDataUpdate = true; +			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); +		} +	} +} + +void LLPanelGroupBulk::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) +{ +	std::vector<std::string> names; +	uuid_vec_t agent_ids; +	agent_ids.push_back(id); +	names.push_back(av_name.getAccountName()); + +	mImplementation->addUsers(names, agent_ids); +} + +void LLPanelGroupBulk::setCloseCallback(void (*close_callback)(void*), void* data) +{ +	mImplementation->mCloseCallback         = close_callback; +	mImplementation->mCloseCallbackUserData = data; +} + +void LLPanelGroupBulk::addUsers(uuid_vec_t& agent_ids) +{ +	std::vector<std::string> names; +	for (S32 i = 0; i < (S32)agent_ids.size(); i++) +	{ +		std::string fullname; +		LLUUID agent_id = agent_ids[i]; +		LLViewerObject* dest = gObjectList.findObject(agent_id); +		if(dest && dest->isAvatar()) +		{ +			LLNameValue* nvfirst = dest->getNVPair("FirstName"); +			LLNameValue* nvlast = dest->getNVPair("LastName"); +			if(nvfirst && nvlast) +			{ +				fullname = LLCacheName::buildFullName( +					nvfirst->getString(), nvlast->getString()); + +			} +			if (!fullname.empty()) +			{ +				names.push_back(fullname); +			}  +			else  +			{ +				llwarns << "llPanelGroupBulk: Selected avatar has no name: " << dest->getID() << llendl; +				names.push_back("(Unknown)"); +			} +		} +		else +		{ +			//looks like user try to invite offline friend +			//for offline avatar_id gObjectList.findObject() will return null +			//so we need to do this additional search in avatar tracker, see EXT-4732 +			if (LLAvatarTracker::instance().isBuddy(agent_id)) +			{ +				LLAvatarName av_name; +				if (!LLAvatarNameCache::get(agent_id, &av_name)) +				{ +					// actually it should happen, just in case +					LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupBulk::addUserCallback, this, _1, _2)); +					// for this special case! +					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence +					// removed id will be added in callback +					agent_ids.erase(agent_ids.begin() + i); +				} +				else +				{ +					names.push_back(av_name.getAccountName()); +				} +			} +		} +	} +	mImplementation->addUsers(names, agent_ids); +} + diff --git a/indra/newview/llpanelgroupbulk.h b/indra/newview/llpanelgroupbulk.h new file mode 100644 index 0000000000..222931eabc --- /dev/null +++ b/indra/newview/llpanelgroupbulk.h @@ -0,0 +1,74 @@ +/**  +* @file   llpanelgroupbulk.h +* @brief  Header file for llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ +#ifndef LL_LLPANELGROUPBULK_H +#define LL_LLPANELGROUPBULK_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLAvatarName; +class LLGroupMgrGroupData; +class LLPanelGroupBulkImpl; + +// Base panel class for bulk group invite / ban floaters +class LLPanelGroupBulk : public LLPanel +{ +public: +	LLPanelGroupBulk(const LLUUID& group_id); +	~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 + diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp new file mode 100644 index 0000000000..57bab0c813 --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.cpp @@ -0,0 +1,156 @@ +/**  +* @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 "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + + +LLPanelGroupBulkBan::LLPanelGroupBulkBan(const LLUUID& group_id) : LLPanelGroupBulk(group_id) +{ +	// Pass on construction of this panel to the control factory. +	buildFromFile( "panel_group_bulk_ban.xml"); +} + +BOOL LLPanelGroupBulkBan::postBuild() +{ +	BOOL recurse = TRUE; + +	mImplementation->mLoadingText = getString("loading"); +	mImplementation->mGroupName = getChild<LLTextBox>("group_name_text", recurse); +	mImplementation->mBulkAgentList = getChild<LLNameListCtrl>("banned_agent_list", recurse); +	if ( mImplementation->mBulkAgentList ) +	{ +		mImplementation->mBulkAgentList->setCommitOnSelectionChange(TRUE); +		mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation); +	} + +	LLButton* button = getChild<LLButton>("add_button", recurse); +	if ( button ) +	{ +		// default to opening avatarpicker automatically +		// (*impl::callbackClickAdd)((void*)this); +		button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this); +	} + +	mImplementation->mRemoveButton =  +		getChild<LLButton>("remove_button", recurse); +	if ( mImplementation->mRemoveButton ) +	{ +		mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); +		mImplementation->mRemoveButton->setEnabled(FALSE); +	} + +	mImplementation->mOKButton =  +		getChild<LLButton>("ban_button", recurse); +	if ( mImplementation->mOKButton ) +	{ +		mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); +		mImplementation->mOKButton->setEnabled(FALSE); +	} + +	button = getChild<LLButton>("cancel_button", recurse); +	if ( button ) +	{ +		button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); +	} + +	mImplementation->mTooManySelected = getString("ban_selection_too_large"); + +	update(); + +	// 	return (mImplementation->mRoleNames && +	// 		mImplementation->mBannedAgents && +	// 		mImplementation->mRemoveButton); + +	return (mImplementation->mBulkAgentList && +		mImplementation->mRemoveButton); +} + + +void LLPanelGroupBulkBan::callbackClickSubmit(void* userdata) +{ +	LLPanelGroupBulkBan* selfp = (LLPanelGroupBulkBan*)userdata; + +	if(selfp) +		selfp->submit(); +} + + +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; +	} + +	LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_PUT, mImplementation->mGroupID, banned_agent_list); + +	// BAKER TEMP: +	//	For now, don't close, but clear the list. +	mImplementation->mBulkAgentList->deleteAllItems(); + +	//then close +	//(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); +} + + + + diff --git a/indra/newview/llpanelgroupbulkban.h b/indra/newview/llpanelgroupbulkban.h new file mode 100644 index 0000000000..0684f365a0 --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.h @@ -0,0 +1,47 @@ +/**  +* @file   llpanelgroupbulkban.h +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLPANELGROUPBULKBAN_H +#define LL_LLPANELGROUPBULKBAN_H + +#include "llpanel.h" +#include "lluuid.h" +#include "llpanelgroupbulk.h" + +class LLAvatarName; + +class LLPanelGroupBulkBan : public LLPanelGroupBulk +{ +public: +	LLPanelGroupBulkBan(const LLUUID& group_id); +	~LLPanelGroupBulkBan() {} + +	virtual BOOL postBuild(); + +	static void callbackClickSubmit(void* userdata); +	virtual void submit(); +}; + +#endif // LL_LLPANELGROUPBULKBAN_H diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h new file mode 100644 index 0000000000..74da542eb8 --- /dev/null +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -0,0 +1,87 @@ +/**  +* @file   llpanelgroupbulkimpl.h +* @brief  Header file for llpanelgroupbulkimpl +* @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; + +class LLPanelGroupBulkImpl +{ +public: +	LLPanelGroupBulkImpl(const LLUUID& group_id); +	~LLPanelGroupBulkImpl(); + +	static void callbackClickAdd(void* userdata); +	static void callbackClickRemove(void* userdata); + +	static void callbackClickCancel(void* userdata); + +	static void callbackSelect(LLUICtrl* ctrl, void* userdata); +	static void callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data); + +	static void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data); + +	void handleRemove(); +	void handleSelection(); + +	void addUsers(const std::vector<std::string>& names, const uuid_vec_t& agent_ids); +	void setGroupName(std::string name); + + +public: +	LLUUID			mGroupID; + +	LLNameListCtrl*	mBulkAgentList; +	LLButton*		mOKButton; +	LLButton*		mRemoveButton; +	LLTextBox*		mGroupName; + +	std::string		mLoadingText; +	std::string		mTooManySelected; + +	void (*mCloseCallback)(void* data); +	void* mCloseCallbackUserData; +	boost::signals2::connection mAvatarNameCacheConnection; + +	// The following are for the LLPanelGroupInvite subclass only.   +	// These aren't needed for LLPanelGroupBulkBan, but if we have to add another  +	// group bulk floater for some reason, we'll have these objects too. +public: +	LLComboBox*		mRoleNames; +	std::string		mOwnerWarning; +	std::string		mAlreadyInGroup; +	bool			mConfirmedOwnerInvite; +}; + +#endif // LL_LLPANELGROUPBULKIMPL_H + diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 133b269c11..c990584d22 100755 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -26,6 +26,8 @@  #include "llviewerprecompiledheaders.h"  #include "llpanelgroupinvite.h" +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h"  #include "llagent.h"  #include "llavatarnamecache.h" @@ -45,203 +47,216 @@  #include "lluictrlfactory.h"  #include "llviewerwindow.h" -class LLPanelGroupInvite::impl + +// BAKER TODO: +// Figure out how to use LLHandle<LLPanel> to make this safer +//bool invite_owner_callback(LLPanelGroupInvite panel, const LLSD& notification, const LLSD& response) +bool invite_owner_callback(LLHandle<LLPanel> panel_handle, const LLSD& notification, const LLSD& response)  { -public: -	impl(const LLUUID& group_id); -	~impl(); - -	void addUsers(const std::vector<std::string>& names, -				  const uuid_vec_t& agent_ids); -	void submitInvitations(); -	void addRoleNames(LLGroupMgrGroupData* gdatap); -	void handleRemove(); -	void handleSelection(); - -	static void callbackClickCancel(void* userdata); -	static void callbackClickOK(void* userdata); -	static void callbackClickAdd(void* userdata); -	static void callbackClickRemove(void* userdata); -	static void callbackSelect(LLUICtrl* ctrl, void* userdata); -	static void callbackAddUsers(const uuid_vec_t& agent_ids, -								 void* user_data); -	 -	static void onAvatarNameCache(const LLUUID& agent_id, -											 const LLAvatarName& av_name, -											 void* user_data); - -	bool inviteOwnerCallback(const LLSD& notification, const LLSD& response); - -public: -	LLUUID mGroupID; - -	std::string		mLoadingText; -	LLNameListCtrl	*mInvitees; -	LLComboBox      *mRoleNames; -	LLButton		*mOKButton; - 	LLButton		*mRemoveButton; -	LLTextBox		*mGroupName; -	std::string		mOwnerWarning; -	std::string		mAlreadyInGroup; -	std::string		mTooManySelected; -	bool		mConfirmedOwnerInvite; - -	void (*mCloseCallback)(void* data); - -	void* mCloseCallbackUserData; - -	boost::signals2::connection mAvatarNameCacheConnection; -}; - - -LLPanelGroupInvite::impl::impl(const LLUUID& group_id): -	mGroupID( group_id ), -	mLoadingText (), -	mInvitees ( NULL ), -	mRoleNames( NULL ), -	mOKButton ( NULL ), -	mRemoveButton( NULL ), -	mGroupName( NULL ), -	mConfirmedOwnerInvite( false ), -	mCloseCallback( NULL ), -	mCloseCallbackUserData( NULL ), -	mAvatarNameCacheConnection() +	LLPanelGroupInvite* panel = dynamic_cast<LLPanelGroupInvite*>(panel_handle.get()); +	if(!panel) +		return false; + +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	switch(option) +	{ +	case 0: +		// user confirmed that they really want a new group owner +		panel->mImplementation->mConfirmedOwnerInvite = true; +		panel->submit(); +		break; +	case 1: +		// fall through +	default: +		break; +	} + 	return false; +} + + +LLPanelGroupInvite::LLPanelGroupInvite(const LLUUID& group_id) : LLPanelGroupBulk(group_id)  { +	// Pass on construction of this panel to the control factory. +	buildFromFile( "panel_group_invite.xml");  } -LLPanelGroupInvite::impl::~impl() +void LLPanelGroupInvite::clear()  { -	if (mAvatarNameCacheConnection.connected()) +	LLPanelGroupBulk::clear(); + +	if(mImplementation->mRoleNames)  	{ -		mAvatarNameCacheConnection.disconnect(); +		mImplementation->mRoleNames->clear(); +		mImplementation->mRoleNames->removeall(); +		mImplementation->mRoleNames->setCurrentByID(LLUUID::null);  	}  } -void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names, -										const uuid_vec_t& agent_ids) +void LLPanelGroupInvite::update()  { -	std::string name; -	LLUUID id; +	LLPanelGroupBulk::update(); -	for (S32 i = 0; i < (S32)names.size(); i++) +	if(mImplementation->mRoleNames)  	{ -		name = names[i]; -		id = agent_ids[i]; - -		// Make sure this agent isn't already in the list. -		bool already_in_list = false; -		std::vector<LLScrollListItem*> items = mInvitees->getAllData(); -		for (std::vector<LLScrollListItem*>::iterator iter = items.begin(); -			 iter != items.end(); ++iter) +		LLUUID store_selected_role = mImplementation->mRoleNames->getCurrentID(); +		mImplementation->mRoleNames->clear(); +		mImplementation->mRoleNames->removeall(); +		mImplementation->mRoleNames->setCurrentByID(LLUUID::null); + +		if(!mPendingRoleDataUpdate && !mPendingMemberDataUpdate)  		{ -			LLScrollListItem* item = *iter; -			if (item->getUUID() == id) -			{ -				already_in_list = true; -				break; -			} +			////////////////////////////////////////////////////////////////////////// +			// Add role names +			 addRoleNames(); +			//////////////////////////////////////////////////////////////////////////// +			mImplementation->mRoleNames->setCurrentByID(store_selected_role);  		} -		if (already_in_list) +		else  		{ -			continue; +			mImplementation->mRoleNames->add(mImplementation->mLoadingText, LLUUID::null, ADD_BOTTOM);  		} +		 +	} +} + +BOOL LLPanelGroupInvite::postBuild() +{ +	BOOL recurse = TRUE; -		//add the name to the names list -		LLSD row; -		row["id"] = id; -		row["columns"][0]["value"] = name; +	mImplementation->mLoadingText = getString("loading"); +	mImplementation->mRoleNames = getChild<LLComboBox>("role_name", +															   recurse); +	mImplementation->mGroupName = getChild<LLTextBox>("group_name_text", recurse); +	mImplementation->mBulkAgentList = getChild<LLNameListCtrl>("invitee_list", recurse); +	if ( mImplementation->mBulkAgentList ) +	{ +		mImplementation->mBulkAgentList->setCommitOnSelectionChange(TRUE); +		mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation); +	} -		mInvitees->addElement(row); +	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>("invite_button", recurse); +	if ( mImplementation->mOKButton ) + 	{ +		mImplementation->mOKButton->setClickedCallback(LLPanelGroupInvite::callbackClickSubmit, this); +		mImplementation->mOKButton->setEnabled(FALSE); + 	} + +	button = getChild<LLButton>("cancel_button", recurse); +	if ( button ) +	{ +		button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); +	} + +	mImplementation->mOwnerWarning = getString("confirm_invite_owner_str"); +	mImplementation->mAlreadyInGroup = getString("already_in_group"); +	mImplementation->mTooManySelected = getString("invite_selection_too_large"); + +	update(); +	 +	return (mImplementation->mRoleNames && +			mImplementation->mBulkAgentList && +			mImplementation->mRemoveButton); +} + +void LLPanelGroupInvite::callbackClickSubmit(void* userdata) +{ +	LLPanelGroupInvite* selfp = (LLPanelGroupInvite*)userdata; + +	if(selfp) +		selfp->submit();  } -void LLPanelGroupInvite::impl::submitInvitations() +void LLPanelGroupInvite::submit()  {  	std::map<LLUUID, LLUUID> role_member_pairs; -	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); +	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID);  	// Default to everyone role.  	LLUUID role_id = LLUUID::null; -	if (mRoleNames) +	if (mImplementation->mRoleNames)  	{ -		role_id = mRoleNames->getCurrentID(); -		 +		role_id = mImplementation->mRoleNames->getCurrentID(); + +		//LLUUID t_ownerUUID = gdatap->mOwnerRole; +		//bool t_confirmInvite = mImplementation->mConfirmedOwnerInvite; +  		// owner role: display confirmation and wait for callback -		if ((role_id == gdatap->mOwnerRole) && (!mConfirmedOwnerInvite)) +		if ((role_id == gdatap->mOwnerRole) && (!mImplementation->mConfirmedOwnerInvite))  		{  			LLSD args; -			args["MESSAGE"] = mOwnerWarning; -			LLNotificationsUtil::add("GenericAlertYesCancel", args, LLSD(), boost::bind(&LLPanelGroupInvite::impl::inviteOwnerCallback, this, _1, _2)); +			args["MESSAGE"] = mImplementation->mOwnerWarning; +			LLNotificationsUtil::add(	"GenericAlertYesCancel",  +										args,  +										LLSD(),  +										boost::bind(invite_owner_callback,  +													this->getHandle(),  +													_1, _2));  			return; // we'll be called again if user confirms  		}  	}  	bool already_in_group = false;  	//loop over the users -	std::vector<LLScrollListItem*> items = mInvitees->getAllData(); +	std::vector<LLScrollListItem*> items = mImplementation->mBulkAgentList->getAllData();  	for (std::vector<LLScrollListItem*>::iterator iter = items.begin(); -		 iter != items.end(); ++iter) +		iter != items.end(); ++iter)  	{  		LLScrollListItem* item = *iter; -		if(LLGroupActions::isAvatarMemberOfGroup(mGroupID, item->getUUID())) +		if(LLGroupActions::isAvatarMemberOfGroup(mImplementation->mGroupID, item->getUUID()))  		{  			already_in_group = true;  			continue;  		}  		role_member_pairs[item->getUUID()] = role_id;  	} -	 +  	const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap.  	if (role_member_pairs.size() > MAX_GROUP_INVITES)  	{  		// Fail!  		LLSD msg; -		msg["MESSAGE"] = mTooManySelected; +		msg["MESSAGE"] = mImplementation->mTooManySelected;  		LLNotificationsUtil::add("GenericAlert", msg); -		(*mCloseCallback)(mCloseCallbackUserData); +		(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);  		return;  	} -	LLGroupMgr::getInstance()->sendGroupMemberInvites(mGroupID, role_member_pairs); -	 +	LLGroupMgr::getInstance()->sendGroupMemberInvites(mImplementation->mGroupID, role_member_pairs); +  	if(already_in_group)  	{  		LLSD msg; -		msg["MESSAGE"] = mAlreadyInGroup; +		msg["MESSAGE"] = mImplementation->mAlreadyInGroup;  		LLNotificationsUtil::add("GenericAlert", msg);  	}  	//then close -	(*mCloseCallback)(mCloseCallbackUserData); +	(*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData);  } -bool LLPanelGroupInvite::impl::inviteOwnerCallback(const LLSD& notification, const LLSD& response) +void LLPanelGroupInvite::addRoleNames()  { -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - -	switch(option) -	{ -	case 0: -		// user confirmed that they really want a new group owner -		mConfirmedOwnerInvite = true; -		submitInvitations(); -		break; -	case 1: -		// fall through -	default: -		break; -	} -	return false; -} - +	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); - -void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap) -{ -	LLGroupMgrGroupData::member_list_t::iterator agent_iter = -		gdatap->mMembers.find(gAgent.getID()); +	LLGroupMgrGroupData::member_list_t::iterator agent_iter = gdatap->mMembers.find(gAgent.getID());  	//get the member data for the agent if it exists  	if ( agent_iter != gdatap->mMembers.end() ) @@ -251,7 +266,7 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap)  		//loop over the agent's roles in the group  		//then add those roles to the list of roles that the agent  		//can invite people to be -		if ( member_data && mRoleNames) +		if ( member_data && mImplementation->mRoleNames)  		{  			//if the user is the owner then we add  			//all of the roles in the group @@ -261,10 +276,10 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap)  			//we add every role the user is in  			//else we just add to everyone  			bool is_owner   = member_data->isInRole(gdatap->mOwnerRole); -			bool can_assign_any = gAgent.hasPowerInGroup(mGroupID, -												 GP_ROLE_ASSIGN_MEMBER); -			bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID, -												 GP_ROLE_ASSIGN_MEMBER_LIMITED); +			bool can_assign_any = gAgent.hasPowerInGroup(mImplementation->mGroupID, +				GP_ROLE_ASSIGN_MEMBER); +			bool can_assign_limited = gAgent.hasPowerInGroup(mImplementation->mGroupID, +				GP_ROLE_ASSIGN_MEMBER_LIMITED);  			LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.begin();  			LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end(); @@ -279,394 +294,18 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap)  					// Owners can add any role.  					if ( is_owner   						// Even 'can_assign_any' can't add owner role. -						 || (can_assign_any && role_id != gdatap->mOwnerRole) +						|| (can_assign_any && role_id != gdatap->mOwnerRole)  						// Add all roles user is in -						 || (can_assign_limited && member_data->isInRole(role_id)) +						|| (can_assign_limited && member_data->isInRole(role_id))  						// Everyone role. -						 || role_id == LLUUID::null ) +						|| role_id == LLUUID::null )  					{ -							mRoleNames->add(rd.mRoleName, -											role_id, -											ADD_BOTTOM); +						mImplementation->mRoleNames->add(rd.mRoleName, +							role_id, +							ADD_BOTTOM);  					}  				}  			}  		}//end if member data is not null  	}//end if agent is in the group  } - -//static -void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata) -{ -	LLPanelGroupInvite* panelp = (LLPanelGroupInvite*) userdata; - -	if ( panelp ) -	{ -		//Right now this is hard coded with some knowledge that it is part -		//of a floater since the avatar picker needs to be added as a dependent -		//floater to the parent floater. -		//Soon the avatar picker will be embedded into this panel -		//instead of being it's own separate floater.  But that is next week. -		//This will do for now. -jwolk May 10, 2006 -        LLView * button = panelp->findChild<LLButton>("add_button"); -        LLFloater * root_floater = gFloaterView->getParentFloater(panelp); -		LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( -			boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button); -		if (picker) -		{ -			root_floater->addDependentFloater(picker); -		} -	} -} - -//static -void LLPanelGroupInvite::impl::callbackClickRemove(void* userdata) -{ -	impl* selfp = (impl*) userdata; - -	if ( selfp ) selfp->handleRemove(); -} - -void LLPanelGroupInvite::impl::handleRemove() -{ -	// Check if there is anything selected. -	std::vector<LLScrollListItem*> selection =  -			mInvitees->getAllSelected(); -	if (selection.empty()) return; - -	// Remove all selected invitees. -	mInvitees->deleteSelectedItems(); -	mRemoveButton->setEnabled(FALSE); -} - -// static -void LLPanelGroupInvite::impl::callbackSelect( -									LLUICtrl* ctrl, void* userdata) -{ -	impl* selfp = (impl*) userdata; -	if ( selfp ) selfp->handleSelection(); -} - -void LLPanelGroupInvite::impl::handleSelection() -{ -	// Check if there is anything selected. -	std::vector<LLScrollListItem*> selection =  -			mInvitees->getAllSelected(); -	if (selection.empty()) -	{ -		mRemoveButton->setEnabled(FALSE); -	} -	else -	{ -		mRemoveButton->setEnabled(TRUE); -	} -} - -void LLPanelGroupInvite::impl::callbackClickCancel(void* userdata) -{ -	impl* selfp = (impl*) userdata; - -	if ( selfp )  -	{ -		(*(selfp->mCloseCallback))(selfp->mCloseCallbackUserData); -	} -} - -void LLPanelGroupInvite::impl::callbackClickOK(void* userdata) -{ -	impl* selfp = (impl*) userdata; - -	if ( selfp ) selfp->submitInvitations(); -} - - - -//static -void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data) -{	 -	std::vector<std::string> names; -	for (S32 i = 0; i < (S32)agent_ids.size(); i++) -	{ -		LLAvatarName av_name; -		if (LLAvatarNameCache::get(agent_ids[i], &av_name)) -		{ -			LLPanelGroupInvite::impl::onAvatarNameCache(agent_ids[i], av_name, user_data); -		} -		else  -		{ -			impl* selfp = (impl*) user_data; -			if (selfp) -			{ -				if (selfp->mAvatarNameCacheConnection.connected()) -				{ -					selfp->mAvatarNameCacheConnection.disconnect(); -				} -				// *TODO : Add a callback per avatar name being fetched. -				selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data)); -			} -		} -	}	 -	 -} - -void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id, -											 const LLAvatarName& av_name, -											 void* user_data) -{ -	impl* selfp = (impl*) user_data; - -	if (selfp) -	{ -		if (selfp->mAvatarNameCacheConnection.connected()) -		{ -			selfp->mAvatarNameCacheConnection.disconnect(); -		} -		std::vector<std::string> names; -		uuid_vec_t agent_ids; -		agent_ids.push_back(agent_id); -		names.push_back(av_name.getCompleteName()); -		 -		selfp->addUsers(names, agent_ids); -	} -} - - -LLPanelGroupInvite::LLPanelGroupInvite(const LLUUID& group_id) -	: LLPanel(), -	  mImplementation(new impl(group_id)), -	  mPendingUpdate(FALSE) -{ -	// Pass on construction of this panel to the control factory. -	buildFromFile( "panel_group_invite.xml"); -} - -LLPanelGroupInvite::~LLPanelGroupInvite() -{ -	delete mImplementation; -} - -void LLPanelGroupInvite::setCloseCallback(void (*close_callback)(void*), -										  void* data) -{ -	mImplementation->mCloseCallback         = close_callback; -	mImplementation->mCloseCallbackUserData = data; -} - -void LLPanelGroupInvite::clear() -{ -	mStoreSelected = LLUUID::null; -	mImplementation->mInvitees->deleteAllItems(); -	mImplementation->mRoleNames->clear(); -	mImplementation->mRoleNames->removeall(); -	mImplementation->mOKButton->setEnabled(FALSE); -} - -void LLPanelGroupInvite::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 << "llPanelGroupInvite: 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(&LLPanelGroupInvite::addUserCallback, this, _1, _2)); -					// for this special case! -					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence -					// removed id will be added in callback -					agent_ids.erase(agent_ids.begin() + i); -				} -				else -				{ -					names.push_back(av_name.getAccountName()); -				} -			} -		} -	} -	mImplementation->addUsers(names, agent_ids); -} - -void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) -{ -	std::vector<std::string> names; -	uuid_vec_t agent_ids; -	agent_ids.push_back(id); -	names.push_back(av_name.getAccountName()); - -	mImplementation->addUsers(names, agent_ids); -} - -void LLPanelGroupInvite::draw() -{ -	LLPanel::draw(); -	if (mPendingUpdate) -	{ -		updateLists(); -	} -} -  -void LLPanelGroupInvite::update() -{ -	mPendingUpdate = FALSE; -	if (mImplementation->mGroupName)  -	{ -		mImplementation->mGroupName->setText(mImplementation->mLoadingText); -	} -	if ( mImplementation->mRoleNames )  -	{ -		mStoreSelected = mImplementation->mRoleNames->getCurrentID(); -		mImplementation->mRoleNames->clear(); -		mImplementation->mRoleNames->removeall(); -		mImplementation->mRoleNames->add(mImplementation->mLoadingText, LLUUID::null, ADD_BOTTOM); -		mImplementation->mRoleNames->setCurrentByID(LLUUID::null); -	} - -	updateLists(); -} - -void LLPanelGroupInvite::updateLists() -{ -	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); -	bool waiting = false; - -	if (gdatap)  -	{ -		if (gdatap->isGroupPropertiesDataComplete())  -		{ -			if (mImplementation->mGroupName)  -			{ -				mImplementation->mGroupName->setText(gdatap->mName); -			} -		}  -		else  -		{ -			waiting = true; -		} -		if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete())  -		{ -			if ( mImplementation->mRoleNames ) -			{ -				mImplementation->mRoleNames->clear(); -				mImplementation->mRoleNames->removeall(); - -				//add the role names and select the everybody role by default -				mImplementation->addRoleNames(gdatap); -				mImplementation->mRoleNames->setCurrentByID(mStoreSelected); -			} -		}  -		else  -		{ -			waiting = true; -		} -	}  -	else  -	{ -		waiting = true; -	} - -	if (waiting)  -	{ -		if (!mPendingUpdate)  -		{ -			LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); -			LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); -			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); -		} -		mPendingUpdate = TRUE; -	}  -	else -	{ -		mPendingUpdate = FALSE; -		if (mImplementation->mOKButton && mImplementation->mRoleNames->getItemCount())  -		{ -			mImplementation->mOKButton->setEnabled(TRUE); -		} -	} -} - -BOOL LLPanelGroupInvite::postBuild() -{ -	BOOL recurse = TRUE; - -	mImplementation->mLoadingText = getString("loading"); -	mImplementation->mRoleNames = getChild<LLComboBox>("role_name", -															   recurse); -	mImplementation->mGroupName = getChild<LLTextBox>("group_name_text", recurse); -	mImplementation->mInvitees =  -		getChild<LLNameListCtrl>("invitee_list", recurse); -	if ( mImplementation->mInvitees ) -	{ -		mImplementation->mInvitees->setCommitOnSelectionChange(TRUE); -		mImplementation->mInvitees->setCommitCallback(impl::callbackSelect, mImplementation); -	} - -	LLButton* button = getChild<LLButton>("add_button", recurse); -	if ( button ) -	{ -		// default to opening avatarpicker automatically -		// (*impl::callbackClickAdd)((void*)this); -		button->setClickedCallback(impl::callbackClickAdd, this); -	} - -	mImplementation->mRemoveButton =  -			getChild<LLButton>("remove_button", recurse); -	if ( mImplementation->mRemoveButton ) -	{ -		mImplementation->mRemoveButton->setClickedCallback(impl::callbackClickRemove, mImplementation); -		mImplementation->mRemoveButton->setEnabled(FALSE); -	} - -	mImplementation->mOKButton =  -		getChild<LLButton>("ok_button", recurse); -	if ( mImplementation->mOKButton ) - 	{ -		mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation); -		mImplementation->mOKButton->setEnabled(FALSE); - 	} - -	button = getChild<LLButton>("cancel_button", recurse); -	if ( button ) -	{ -		button->setClickedCallback(impl::callbackClickCancel, mImplementation); -	} - -	mImplementation->mOwnerWarning = getString("confirm_invite_owner_str"); -	mImplementation->mAlreadyInGroup = getString("already_in_group"); -	mImplementation->mTooManySelected = getString("invite_selection_too_large"); - -	update(); -	 -	return (mImplementation->mRoleNames && -			mImplementation->mInvitees && -			mImplementation->mRemoveButton); -} diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h index 9f7b5ae9be..b87a5883b8 100755 --- a/indra/newview/llpanelgroupinvite.h +++ b/indra/newview/llpanelgroupinvite.h @@ -27,36 +27,27 @@  #define LL_LLPANELGROUPINVITE_H  #include "llpanel.h" +#include "llpanelgroupbulk.h"  #include "lluuid.h"  class LLAvatarName; -class LLPanelGroupInvite -: public LLPanel +class LLPanelGroupInvite : public LLPanelGroupBulk  {  public:  	LLPanelGroupInvite(const LLUUID& group_id); -	~LLPanelGroupInvite(); +	~LLPanelGroupInvite() {}; -	void addUsers(uuid_vec_t& agent_ids); -	/** -	 * this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers(). -	 */   -	void addUserCallback(const LLUUID& id, const LLAvatarName& av_name); -	void clear(); -	void update(); +	virtual void clear(); +	virtual void update(); -	void setCloseCallback(void (*close_callback)(void*), void* data); - -	virtual void draw();  	virtual BOOL postBuild(); -protected: -	class impl; -	impl* mImplementation; -	BOOL mPendingUpdate; -	LLUUID mStoreSelected; -	void updateLists(); +	static void callbackClickSubmit(void* userdata); +	virtual void submit(); + +private: +	void addRoleNames();  };  #endif diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index cfdac11d26..8d7b3c38ee 100755 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -32,6 +32,7 @@  #include "llavatarnamecache.h"  #include "llbutton.h"  #include "llfiltereditor.h" +#include "llfloatergroupbulkban.h"  #include "llfloatergroupinvite.h"  #include "llavataractions.h"  #include "lliconctrl.h" @@ -109,8 +110,9 @@ bool agentCanAddToRole(const LLUUID& group_id,  	return false;  } -// static +// LLPanelGroupRoles ///////////////////////////////////////////////////// +// static  LLPanelGroupRoles::LLPanelGroupRoles()  :	LLPanelGroupTab(),  	mCurrentTab(NULL), @@ -412,6 +414,35 @@ BOOL LLPanelGroupRoles::hasModal()  	return panelp->hasModal();  } +// BAKER -- Moved this from all the way at the bottom +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(0); + +	activate(); +} + +////////////////////////////////////////////////////////////////////////// + + +// LLPanelGroupSubTab ////////////////////////////////////////////////////  ////////////////////////////  // LLPanelGroupSubTab @@ -728,11 +759,14 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable)  	}  } +////////////////////////////////////////////////////////////////////////// + + +// LLPanelGroupMembersSubTab ///////////////////////////////////////////// +  ////////////////////////////  // LLPanelGroupMembersSubTab  //////////////////////////// - -  static LLRegisterPanelClassWrapper<LLPanelGroupMembersSubTab> t_panel_group_members_subtab("panel_group_members_subtab");  LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab() @@ -810,6 +844,14 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)  		mEjectBtn->setEnabled(FALSE);  	} +	mBanBtn = parent->getChild<LLButton>("member_ban", recurse); +	if(mBanBtn) +	{ +		mBanBtn->setClickedCallback(onBanMember, this); +		mBanBtn->setEnabled(FALSE); +	} + +  	return TRUE;  } @@ -823,34 +865,6 @@ void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id)  	LLPanelGroupSubTab::setGroupID(id);  } -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); -} -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); -} - -  // static  void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data)  { @@ -916,6 +930,12 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()  	LLGroupMgrGroupData::role_list_t::iterator iter = gdatap->mRoles.begin();  	LLGroupMgrGroupData::role_list_t::iterator end  = gdatap->mRoles.end(); +	////////////////////////////////////////////////////////////////////////// +	// BAKER STUB: +	// Check if the member has the power to ban (just like the eject below) +	// Right now, just give it to them (for testing) +	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; @@ -986,6 +1006,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()  			if (role_id.notNull() && (count > 0))  			{  				can_eject_members = FALSE; +				can_ban_members = FALSE;  				if (role_id == gdatap->mOwnerRole)  				{  					member_is_owner = TRUE; @@ -1047,7 +1068,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)  	{ @@ -1060,10 +1084,12 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()  			if ( member_data && member_data->isInRole(gdatap->mOwnerRole) )  			{  				can_eject_members = TRUE; +				can_ban_members = TRUE;  			}  		}  	} +	mBanBtn->setEnabled(can_ban_members);  	mEjectBtn->setEnabled(can_eject_members);  } @@ -1231,7 +1257,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,  					 FALSE);  } -  // static   void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data)  { @@ -1653,7 +1678,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  		return;  	} -	//cleanup list only for first iretation +	//cleanup list only for first iteration  	if(mMemberProgress == gdatap->mMembers.begin())  	{  		mMembersList->deleteAllItems(); @@ -1712,12 +1737,55 @@ void LLPanelGroupMembersSubTab::updateMembers()  	handleMemberSelect();  } +// BAKER +void LLPanelGroupMembersSubTab::onBanMember(void* user_data) +{ +	LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data); +	self->handleBanMember(); +} +void LLPanelGroupMembersSubTab::handleBanMember() +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupMembersSubTab::handleBanMember()" << LL_ENDL; + +	LLGroupMgrGroupData* gdatap	= LLGroupMgr::getInstance()->getGroupData(mGroupID); +	if(!gdatap)  +	{ +		llwarns << "LLPanelGroupMembersSubTab::handleMemberSelect() " +			<< "-- No group data!" << llendl; +		return; +	} + +	std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); +	if(selection.empty()) +	{ +		LL_WARNS("BAKER") << "[BAKER] Empty selection!" << LL_ENDL; +		return; +	} + +	std::vector<LLScrollListItem*>::iterator itor; +	for(itor = selection.begin(); itor != selection.end(); ++itor) +	{ +		LLUUID ban_id = (*itor)->getUUID(); +		LLGroupBanData ban_data; + +		// DEL to People API somewhere in this chain... +		gdatap->createBanEntry(ban_id, ban_data); +		mMembersList->removeNameItem(ban_id); + +	}	 + + +} + +////////////////////////////////////////////////////////////////////////// + + +// LLPanelGroupRolesSubTab ///////////////////////////////////////////////  ////////////////////////////  // LLPanelGroupRolesSubTab  //////////////////////////// -  static LLRegisterPanelClassWrapper<LLPanelGroupRolesSubTab> t_panel_group_roles_subtab("panel_group_roles_subtab");  LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() @@ -1962,7 +2030,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)  		mRolesList->sortByColumn(std::string("name"), TRUE);  		if ( (gdatap->mRoles.size() < (U32)MAX_ROLES) -			&& gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE) ) +			&& gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS) )  		{  			mCreateRoleButton->setEnabled(TRUE);  		} @@ -2010,6 +2078,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();  } @@ -2250,7 +2321,6 @@ bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD&  	return false;  } -  // static  void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data)  { @@ -2428,13 +2498,34 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role)  		mHasRoleChange = FALSE;  	}  } + +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 ///////////////////////////////////////////// +  ////////////////////////////  // LLPanelGroupActionsSubTab  //////////////////////////// -  static LLRegisterPanelClassWrapper<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab"); -  LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab()  : LLPanelGroupSubTab()  { @@ -2607,26 +2698,343 @@ void LLPanelGroupActionsSubTab::handleActionSelect()  	}  } -void LLPanelGroupRoles::setGroupID(const LLUUID& id) +void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id)  { -	LLPanelGroupTab::setGroupID(id); +	if(mActionList) mActionList->deleteAllItems(); +	if(mActionRoles) mActionRoles->deleteAllItems(); +	if(mActionMembers) mActionMembers->deleteAllItems(); + +	if(mActionDescription) mActionDescription->clear(); + +	LLPanelGroupSubTab::setGroupID(id); +} + +////////////////////////////////////////////////////////////////////////// + + +//////////////////////////// +// LLPanelGroupBanListSubTab +//////////////////////////// +static LLRegisterPanelClassWrapper<LLPanelGroupBanListSubTab> t_panel_group_ban_subtab("panel_group_banlist_subtab"); + +LLPanelGroupBanListSubTab::LLPanelGroupBanListSubTab() +	: LLPanelGroupSubTab(), +	  mBanList(NULL), +	  mCreateBanButton(NULL), +	  mDeleteBanButton(NULL), +	  mUpdateBanList(true) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::ctor()" << LL_ENDL; +} + +BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::postBuildSubTab()" << LL_ENDL; + +	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; -	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"); +	// BAKER TODO: +	//	What are these? Looks like something inhereted from LLPanelGroupSubTab +	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); -	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(!mBanList || !mCreateBanButton || !mDeleteBanButton) +		return FALSE; -	LLButton* button = getChild<LLButton>("member_invite"); -	if ( button ) -		button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); +	mBanList->setCommitOnSelectionChange(TRUE); +	mBanList->setCommitCallback(onBanEntrySelect, this); -	if(mSubTabContainer) -		mSubTabContainer->selectTab(0); +	mCreateBanButton->setClickedCallback(onCreateBanEntry, this); +	mCreateBanButton->setEnabled(FALSE); +	 +	mDeleteBanButton->setClickedCallback(onDeleteBanEntry, this); +	mDeleteBanButton->setEnabled(FALSE); +	 +	setFooterEnabled(FALSE); -	activate(); +	return TRUE; +} + +void LLPanelGroupBanListSubTab::activate() +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::activate()" << LL_ENDL; +	 +	LLPanelGroupSubTab::activate(); + +	mBanList->deselectAllItems(); +	mDeleteBanButton->setEnabled(FALSE); + +	setFooterEnabled(FALSE); +	update(GC_ALL); +} + +void LLPanelGroupBanListSubTab::deactivate() +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::deactivate()" << LL_ENDL; +	 +	LLPanelGroupSubTab::deactivate(); +} + +bool LLPanelGroupBanListSubTab::needsApply(std::string& mesg) +{ +	LL_INFOS("BAKER") << "LLPanelGroupBanListSubTab::needsApply()" << LL_ENDL; + +	// STUB +	return false; +} + +bool LLPanelGroupBanListSubTab::apply(std::string& mesg) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::apply()" << LL_ENDL; +	 +	 + + +	// STUB +	return true;  } +void LLPanelGroupBanListSubTab::update(LLGroupChange gc) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::update()" << LL_ENDL; + +	if (gc != GC_ALL || gc != GC_BANLIST) +		return; + +	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); +	if(!gdatap)  +	{ +		LL_INFOS("BAKER") << "[BAKER] No group data!" << LL_ENDL; +		return; +	} + +	switch(gdatap->getGroupBanStatus()) +	{ +	// Must be initial update [	Check if I should request this at panel creation +	//							with everything else -- might as well] +	// Request our ban list! +	case LLGroupMgrGroupData::STATUS_INIT: +		LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); +		break; +	 +	// Already have a request out -- don't bother sending another one  +	// Repeat sending won't make a difference, as it'll be behind a load balancer +	case LLGroupMgrGroupData::STATUS_REQUESTING: +		break; +	 +	//	See if the list needs updating -- if we call update, but nothing changed, +	//	there's no reason to send another request. +	//		[NOTHING CHANGED]	- Do Nothing! +	//		[SOMETHING CHANGED]	- Don't panic! Just repopulate the ban list!  +	case LLGroupMgrGroupData::STATUS_COMPLETE: +		populateBanList(); + +		 +		break; +	} +} + + +void LLPanelGroupBanListSubTab::populateBanList() +{ +	//if(gdatap->getGroupBanStatus() == ) + + + +// 	mBanList->deleteAllItems(); +// 	LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); +// 	 +// 	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; +// 		mBanList->addNameItemRow(ban_entry); +// 	} +	 +	mUpdateBanList = false; +} + + +void LLPanelGroupBanListSubTab::onBanEntrySelect(LLUICtrl* ctrl, void* user_data) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::onBanEntrySelect()" << LL_ENDL; +	 +	LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); +	if (!self)  +		return; + +	self->handleBanEntrySelect(); +} + +void LLPanelGroupBanListSubTab::handleBanEntrySelect() +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::handleBanEntrySelect()" << LL_ENDL; + +	// BAKER TODO: -- MOVE TO SELECT BAN ENTRY +	// Make sure only authorized people have access to adding / deleting bans +	//if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) +	mCreateBanButton->setEnabled(TRUE); + +	// Check if the agent has the ability to unban this person +	//if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) +		mDeleteBanButton->setEnabled(TRUE); +} + + +void LLPanelGroupBanListSubTab::onBanGroupMember(void* user_data) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::onBanGroupMember()" << LL_ENDL; + +	LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); +	if (!self)  +		return; + +	self->handleBanGroupMember(); +} + +void LLPanelGroupBanListSubTab::handleBanGroupMember() +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::handleBanGroupMember()" << LL_ENDL; + +	////////////////////////////////////////////////////////////////////////// +	// BAKER TEMP +	//	Getting viewer functionality working, so I'm gonna cheat a bit here for now +	//	Assume everything worked on the back end +	//	 +	//	First, get the entries added to the ban list +	////////////////////////////////////////////////////////////////////////// +	 +} + + +void LLPanelGroupBanListSubTab::onCreateBanEntry(void* user_data) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::onCreateBanEntry()" << LL_ENDL; +	 +	LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); +	if (!self)  +		return; + +	self->handleCreateBanEntry(); +} + +void LLPanelGroupBanListSubTab::handleCreateBanEntry() +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::handleCreateBanEntry()" << LL_ENDL; +	 +	// STUB +	// Attempt to add an entry into the database +	// If there was a problem, don't add the entry to the local list +	// Otherwise, add it +	//  +	// For now, let's just add it to the local list for testing.  We can hook it up +	// at the end. + + +	LLFloaterGroupBulkBan::showForGroup(mGroupID); + +} + + +void LLPanelGroupBanListSubTab::onDeleteBanEntry(void* user_data) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::onDeleteBanEntry()" << LL_ENDL; +	 +	LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); +	if (!self)  +		return; + +	self->handleDeleteBanEntry(); +} + +void LLPanelGroupBanListSubTab::handleDeleteBanEntry() +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::handleDeleteBanEntry()" << LL_ENDL; +	 +	LLGroupMgrGroupData* gdatap	= LLGroupMgr::getInstance()->getGroupData(mGroupID); +	if(!gdatap)  +	{ +		llwarns << "LLPanelGroupMembersSubTab::handleMemberSelect() " +			<< "-- No group data!" << llendl; +		return; +	} + +	std::vector<LLScrollListItem*> selection = mBanList->getAllSelected(); +	if(selection.empty()) +	{ +		LL_WARNS("BAKER") << "[BAKER] Empty selection!" << LL_ENDL; +		return; +	} + +	////////////////////////////////////////////////////////////////////////// +	// BAKER STUB: +	// Check if the member has the power to ban (just like the eject below) +	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; +		} +	} + +	std::vector<LLScrollListItem*>::iterator itor; +	for(itor = selection.begin(); itor != selection.end(); ++itor) +	{ +		// STUB +		// Attempt to remove entry from the database +		// If there was a problem with the delete, don't remove it from the list yet! +		// Otherwise, remove it from our local list. +		//  + +		LLUUID ban_id = (*itor)->getUUID(); +		if(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); +		} +	} +	 + +} + + +void LLPanelGroupBanListSubTab::setGroupID(const LLUUID& id) +{ +	LL_INFOS("BAKER") << "[BAKER] LLPanelGroupBanListSubTab::setGroupID()" << LL_ENDL; +	 +	if(mBanList) +		mBanList->deleteAllItems(); + +	setFooterEnabled(FALSE); +	LLPanelGroupSubTab::setGroupID(id); +} + + + + diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 78bb3c57a1..1695097fc5 100755 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -172,6 +172,10 @@ public:  	void handleRoleCheck(const LLUUID& role_id,  						 LLRoleMemberChangeType type); +	static void onBanMember(void* user_data); +	void handleBanMember(); + +  	void applyMemberChanges();  	bool addOwnerCB(const LLSD& notification, const LLSD& response); @@ -205,6 +209,7 @@ protected:  	LLScrollListCtrl*	mAssignedRolesList;  	LLScrollListCtrl*	mAllowedActionsList;  	LLButton*           mEjectBtn; +	LLButton*			mBanBtn;  	BOOL mChanged;  	BOOL mPendingMemberUpdate; @@ -305,5 +310,57 @@ protected:  	LLTextEditor*	mActionDescription;  }; +class LLPanelGroupBanListSubTab : public LLPanelGroupSubTab +{ +public: +	LLPanelGroupBanListSubTab(); +	virtual ~LLPanelGroupBanListSubTab() {} + +	virtual BOOL postBuildSubTab(LLView* root); + +	// Triggered when the tab becomes active. +	virtual void activate(); +	 +	// Triggered when the tab becomes inactive. +	virtual void deactivate(); +	 +	// Asks if something needs to be applied. +	// If returning true, this function should modify the message to the user. +	virtual bool needsApply(std::string& mesg); +	 +	// Request to apply current data. +	// If returning fail, this function should modify the message to the user. +	virtual bool apply(std::string& mesg); +	 +	// Triggered when group information changes in the group manager. +	virtual void update(LLGroupChange gc); + + +	static void onBanEntrySelect(LLUICtrl* ctrl, void* user_data); +	void handleBanEntrySelect(); + +	static void onBanGroupMember(void* user_data); +	void handleBanGroupMember(); +	 +	static void onCreateBanEntry(void* user_data); +	void handleCreateBanEntry(); +	 +	static void onDeleteBanEntry(void* user_data); +	void handleDeleteBanEntry(); +	 +	virtual void setGroupID(const LLUUID& id); + +protected: +	void populateBanList(); + + +protected: +	LLNameListCtrl* mBanList; +	LLButton* mCreateBanButton; +	LLButton* mDeleteBanButton; + +	bool mUpdateBanList; +	 +};  #endif // LL_LLPANELGROUPROLES_H diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 8422708add..cfbfc983fb 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1600,6 +1600,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("GetObjectCost");  	capabilityNames.append("GetObjectPhysicsData");  	capabilityNames.append("GetTexture"); +	capabilityNames.append("GroupBan");  	capabilityNames.append("GroupMemberData");  	capabilityNames.append("GroupProposalBallot");  	capabilityNames.append("HomeLocation"); diff --git a/indra/newview/skins/default/xui/en/panel_group_bulk_ban.xml b/indra/newview/skins/default/xui/en/panel_group_bulk_ban.xml new file mode 100644 index 0000000000..3baed595da --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_group_bulk_ban.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="330" + label="Ban Residents" + layout="topleft" + left="0" + name="bulk_ban_panel" + top="330" + width="210"> +  <panel.string +   name="loading"> +    (loading...) +  </panel.string> +  <panel.string +     name="ban_selection_too_large"> +    Group Invitations not sent: too many Residents selected. Group Invitations are limited to 100 per request. +  </panel.string> +  <text +   type="string" +   length="1" +   height="54" +   layout="topleft" +   left="7" +   name="help_text" +   top="28" +   word_wrap="true" +   width="200"> +    You can select multiple Residents to ban from your group. Click 'Open Resident Chooser' to start. +  </text> +  <button +   height="20" +   label="Open Resident Chooser" +   layout="topleft" +   left_delta="-2" +   name="add_button" +   top_delta="44" +   width="200" /> +  <name_list +   allow_calling_card_drop="true" +   column_padding="0" +   height="174" +   layout="topleft" +   left_delta="0" +   multi_select="true" +   name="banned_agent_list" +   tool_tip="Hold the Ctrl key and click Resident names to multi-select" +   top_pad="4" +   width="200" /> +  <button +   height="20" +   label="Remove Selected from List" +   layout="topleft" +   left_delta="0" +   name="remove_button" +   tool_tip="Removes the Residents selected above from the ban list" +   top_pad="4" +   width="200" /> +  <button +   height="20" +   label="BAN THIS SICK FILTH" +   layout="topleft" +   left="4" +   name="ban_button" +   top_delta="30" +   width="135" /> +  <button +   height="20" +   label="Cancel" +   layout="topleft" +   left_pad="2" +   name="cancel_button" +   top_delta="0" +   width="65" /> +  <string +  name="GroupBulkBan"> +    Group Ban +  </string> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml index 124c0596c3..944a496fba 100755 --- a/indra/newview/skins/default/xui/en/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml @@ -88,7 +88,7 @@       label="Send Invitations"       layout="topleft"       left="4" -     name="ok_button" +     name="invite_button"       top="356"       width="135" />      <button diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index df91ad8b5e..9817f70ac7 100755 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -114,6 +114,13 @@ clicking on their names.               left_pad="10"               name="member_eject"               width="100" /> +            <button +             height="23" +             label="Ban" +             follows="top|left" +             left_pad="10" +             name="member_ban" +             width="100" />          </panel>          <panel           border="false" @@ -277,6 +284,72 @@ things in this group. There's a broad variety of Abilities.               width="270" />          </scroll_list>          </panel> +        <panel +         border="false" +         height="303" +         label="BANNED AGENTS" +         layout="topleft" +         left="0" +         right="-1" +         help_topic="roles_banlist_tab" +         name="banlist_sub_tab" +         class="panel_group_banlist_subtab" +         tool_tip="View the banned agents from this group." +         width="310"> +        <panel.string +         name="help_text"> +            Any resident on the ban list will be unable to join the group. +        </panel.string> +        <filter_editor +        layout="topleft" +        top="5" +        left="5" +        right="-5" +        height="22" +        search_button_visible="false" +        follows="left|top|right" +        label="Filter Bans" +        name="filter_bans" /> +          <name_list +               column_padding="0" +               draw_heading="true" +               height="240" +               follows="left|top|right" +               layout="topleft" +               left="0" +               right="-1" +               multi_select="true" +               name="ban_list" +               short_names="false" +               top_pad="5"> +            <name_list.columns +             label="Resident" +             name="name" +             font.name="SANSSERIF_SMALL" +             font.style="NORMAL" +           relative_width="0.65" /> +            <name_list.columns +             label="Date Banned" +             name="date_banned" +     relative_width="0.35" /> +          </name_list> +		  <button +            follows="top|left" +             height="23" +             label="Ban!" +             layout="topleft" +             left="3" +             name="ban_create" +             width="120" /> +            <button +             height="23" +             follows="top|left" +             label="Unban!" +             layout="topleft" +             left_pad="10" +             name="ban_delete" +             width="120" /> +      </panel>      </tab_container>      <panel       height="350" diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml index 89aef57cca..79789fcd7b 100755 --- a/indra/newview/skins/default/xui/en/role_actions.xml +++ b/indra/newview/skins/default/xui/en/role_actions.xml @@ -1,5 +1,12 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <role_actions> +  <action_set +      description="These Abilities include powers to ban and un-ban residents from the group." +      name="Bans"> +    <action description="Manage ban list." +            longdescription="Allows the group member to ban / un-ban Residents from this group." +            name="allow ban" value="49" /> +  </action_set>  	<action_set  	     description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation."  	     name="Membership"> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f7b33b0a4a..aa29a88786 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3672,6 +3672,7 @@ Abuse Report</string>    <string name="LocalEstimateUSD">US$ [AMOUNT]</string>    <!-- Group Profile roles and powers --> +  <string name="Group Ban">Group Ban</string>    <string name="Membership">Membership</string>    <string name="Roles">Roles</string>    <string name="Group Identity">Group Identity</string> | 
