summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindra/llcommon/roles_constants.h100
-rwxr-xr-xindra/llcommon/stdenums.h1
-rwxr-xr-xindra/newview/CMakeLists.txt7
-rw-r--r--indra/newview/llfloatergroupbulkban.cpp134
-rw-r--r--indra/newview/llfloatergroupbulkban.h48
-rwxr-xr-xindra/newview/llgroupmgr.cpp172
-rwxr-xr-xindra/newview/llgroupmgr.h83
-rw-r--r--indra/newview/llpanelgroupbulk.cpp403
-rw-r--r--indra/newview/llpanelgroupbulk.h74
-rw-r--r--indra/newview/llpanelgroupbulkban.cpp156
-rw-r--r--indra/newview/llpanelgroupbulkban.h47
-rw-r--r--indra/newview/llpanelgroupbulkimpl.h87
-rwxr-xr-xindra/newview/llpanelgroupinvite.cpp673
-rwxr-xr-xindra/newview/llpanelgroupinvite.h29
-rwxr-xr-xindra/newview/llpanelgrouproles.cpp512
-rwxr-xr-xindra/newview/llpanelgrouproles.h57
-rwxr-xr-xindra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_bulk_ban.xml78
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_group_invite.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_group_roles.xml73
-rwxr-xr-xindra/newview/skins/default/xui/en/role_actions.xml7
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml1
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 &apos;Open Resident Chooser&apos; 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&apos;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>