summaryrefslogtreecommitdiff
path: root/indra/newview/llgroupmgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llgroupmgr.cpp')
-rw-r--r--indra/newview/llgroupmgr.cpp346
1 files changed, 226 insertions, 120 deletions
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index bb6abcd95b..7546c070ea 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -2,30 +2,25 @@
* @file llgroupmgr.cpp
* @brief LLGroupMgr class implementation
*
- * $LicenseInfo:firstyear=2004&license=viewergpl$
- *
- * Copyright (c) 2004-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * 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.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * 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.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * 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$
*/
@@ -49,12 +44,23 @@
#include "llstatusbar.h"
#include "lleconomy.h"
#include "llviewerwindow.h"
-#include "llfloaterdirectory.h"
-#include "llfloatergroupinfo.h"
+#include "llpanelgroup.h"
+#include "llgroupactions.h"
+#include "llnotificationsutil.h"
#include "lluictrlfactory.h"
+#include "lltrans.h"
+#include <boost/regex.hpp>
-LLGroupMgr sGroupMgr; // use local instance so that it gets cleaned up on application exit
-LLGroupMgr* gGroupMgr = &sGroupMgr;
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+#include <boost/lexical_cast.hpp>
+
+#if LL_MSVC
+#pragma warning(pop) // Restore all warnings to the previous state
+#endif
const U32 MAX_CACHED_GROUPS = 10;
@@ -148,7 +154,7 @@ LLGroupRoleData::~LLGroupRoleData()
{
}
-S32 LLGroupRoleData::getMembersInRole(std::vector<LLUUID> members,
+S32 LLGroupRoleData::getMembersInRole(uuid_vec_t members,
BOOL needs_sort)
{
if (mRoleID.isNull())
@@ -172,8 +178,8 @@ S32 LLGroupRoleData::getMembersInRole(std::vector<LLUUID> members,
// Return the number of members in the intersection.
S32 max_size = llmin( members.size(), mMemberIDs.size() );
- std::vector<LLUUID> in_role( max_size );
- std::vector<LLUUID>::iterator in_role_end;
+ uuid_vec_t in_role( max_size );
+ uuid_vec_t::iterator in_role_end;
in_role_end = std::set_intersection(mMemberIDs.begin(), mMemberIDs.end(),
members.begin(), members.end(),
in_role.begin());
@@ -188,7 +194,7 @@ void LLGroupRoleData::addMember(const LLUUID& member)
bool LLGroupRoleData::removeMember(const LLUUID& member)
{
- std::vector<LLUUID>::iterator it = std::find(mMemberIDs.begin(),mMemberIDs.end(),member);
+ uuid_vec_t::iterator it = std::find(mMemberIDs.begin(),mMemberIDs.end(),member);
if (it != mMemberIDs.end())
{
@@ -676,9 +682,12 @@ void LLGroupMgrGroupData::sendRoleChanges()
break;
}
case RC_UPDATE_ALL:
+ // fall through
case RC_UPDATE_POWERS:
need_power_recalc = true;
+ // fall through
case RC_UPDATE_DATA:
+ // fall through
default:
{
LLGroupRoleData* group_role_data = (*role_it).second;
@@ -705,7 +714,7 @@ void LLGroupMgrGroupData::sendRoleChanges()
// If we create a new role, then we need to re-fetch all the role data.
if (need_role_data)
{
- gGroupMgr->sendGroupRoleDataRequest(getID());
+ LLGroupMgr::getInstance()->sendGroupRoleDataRequest(getID());
}
// Clean up change lists
@@ -757,7 +766,16 @@ void LLGroupMgr::clearGroupData(const LLUUID& group_id)
void LLGroupMgr::addObserver(LLGroupMgrObserver* observer)
{
- mObservers.insert(std::pair<LLUUID, LLGroupMgrObserver*>(observer->getID(), observer));
+ if( observer->getID() != LLUUID::null )
+ mObservers.insert(std::pair<LLUUID, LLGroupMgrObserver*>(observer->getID(), observer));
+}
+
+void LLGroupMgr::addObserver(const LLUUID& group_id, LLParticularGroupObserver* observer)
+{
+ if(group_id.notNull() && observer)
+ {
+ mParticularObservers[group_id].insert(observer);
+ }
}
void LLGroupMgr::removeObserver(LLGroupMgrObserver* observer)
@@ -782,6 +800,23 @@ void LLGroupMgr::removeObserver(LLGroupMgrObserver* observer)
}
}
+void LLGroupMgr::removeObserver(const LLUUID& group_id, LLParticularGroupObserver* observer)
+{
+ if(group_id.isNull() || !observer)
+ {
+ return;
+ }
+
+ observer_map_t::iterator obs_it = mParticularObservers.find(group_id);
+ if(obs_it == mParticularObservers.end())
+ return;
+
+ obs_it->second.erase(observer);
+
+ if (obs_it->second.size() == 0)
+ mParticularObservers.erase(obs_it);
+}
+
LLGroupMgrGroupData* LLGroupMgr::getGroupData(const LLUUID& id)
{
group_map_t::iterator gi = mGroups.find(id);
@@ -793,6 +828,26 @@ LLGroupMgrGroupData* LLGroupMgr::getGroupData(const LLUUID& id)
return NULL;
}
+// Helper function for LLGroupMgr::processGroupMembersReply
+// This reformats date strings from MM/DD/YYYY to YYYY/MM/DD ( e.g. 1/27/2008 -> 2008/1/27 )
+// so that the sorter can sort by year before month before day.
+static void formatDateString(std::string &date_string)
+{
+ using namespace boost;
+ cmatch result;
+ const regex expression("([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})");
+ if (regex_match(date_string.c_str(), result, expression))
+ {
+ // convert matches to integers so that we can pad them with zeroes on Linux
+ S32 year = boost::lexical_cast<S32>(result[3]);
+ S32 month = boost::lexical_cast<S32>(result[1]);
+ S32 day = boost::lexical_cast<S32>(result[2]);
+
+ // ISO 8601 date format
+ date_string = llformat("%04d/%02d/%02d", year, month, day);
+ }
+}
+
// static
void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
{
@@ -811,7 +866,7 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
LLUUID request_id;
msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_RequestID, request_id);
- LLGroupMgrGroupData* group_datap = gGroupMgr->createGroupData(group_id);
+ LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->createGroupData(group_id);
if (group_datap->mMemberRequestID != request_id)
{
llwarns << "processGroupMembersReply: Received incorrect (stale?) request id" << llendl;
@@ -823,8 +878,8 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
if (group_datap->mMemberCount > 0)
{
S32 contribution = 0;
- char online_status[DB_DATETIME_BUF_SIZE]; /* Flawfinder: ignore */
- char title[DB_GROUP_TITLE_BUF_SIZE]; /* Flawfinder: ignore */
+ std::string online_status;
+ std::string title;
U64 agent_powers = 0;
BOOL is_owner = FALSE;
@@ -836,18 +891,28 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
msg->getUUIDFast(_PREHASH_MemberData, _PREHASH_AgentID, member_id, i );
msg->getS32(_PREHASH_MemberData, _PREHASH_Contribution, contribution, i);
msg->getU64(_PREHASH_MemberData, "AgentPowers", agent_powers, i);
- msg->getStringFast(_PREHASH_MemberData, _PREHASH_OnlineStatus, DB_DATETIME_BUF_SIZE, online_status, i);
- msg->getString(_PREHASH_MemberData, "Title", DB_GROUP_TITLE_BUF_SIZE, title, i);
+ msg->getStringFast(_PREHASH_MemberData, _PREHASH_OnlineStatus, online_status, i);
+ msg->getString(_PREHASH_MemberData, "Title", title, i);
msg->getBOOL(_PREHASH_MemberData,"IsOwner",is_owner,i);
if (member_id.notNull())
{
+ if (online_status == "Online")
+ {
+ static std::string localized_online(LLTrans::getString("group_member_status_online"));
+ online_status = localized_online;
+ }
+ else
+ {
+ formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25
+ }
+
//llinfos << "Member " << member_id << " has powers " << std::hex << agent_powers << std::dec << llendl;
LLGroupMemberData* newdata = new LLGroupMemberData(member_id,
contribution,
agent_powers,
- std::string(title),
- std::string(online_status),
+ title,
+ online_status,
is_owner);
#if LL_DEBUG
LLGroupMgrGroupData::member_list_t::iterator mit = group_datap->mMembers.find(member_id);
@@ -867,7 +932,7 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
//if group members are loaded while titles are missing, load the titles.
if(group_datap->mTitles.size() < 1)
{
- gGroupMgr->sendGroupTitlesRequest(group_id);
+ LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
}
}
@@ -879,12 +944,12 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
if (group_datap->mPendingRoleMemberRequest)
{
group_datap->mPendingRoleMemberRequest = FALSE;
- gGroupMgr->sendGroupRoleMembersRequest(group_datap->mID);
+ LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID);
}
}
group_datap->mChanged = TRUE;
- gGroupMgr->notifyObservers(GC_MEMBER_DATA);
+ LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
}
//static
@@ -900,13 +965,13 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
}
LLUUID group_id;
- char name[DB_GROUP_NAME_BUF_SIZE]; /* Flawfinder: ignore */
- char charter[DB_GROUP_CHARTER_BUF_SIZE]; /* Flawfinder: ignore */
+ std::string name;
+ std::string charter;
BOOL show_in_list = FALSE;
LLUUID founder_id;
U64 powers_mask = GP_NO_POWERS;
S32 money = 0;
- char member_title[DB_GROUP_TITLE_BUF_SIZE]; /* Flawfinder: ignore */
+ std::string member_title;
LLUUID insignia_id;
LLUUID owner_role;
U32 membership_fee = 0;
@@ -917,23 +982,23 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
BOOL mature = FALSE;
msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id );
- msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_FounderID, founder_id);
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_Name, DB_GROUP_NAME_BUF_SIZE, name );
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_Charter, DB_GROUP_CHARTER_BUF_SIZE, charter );
- msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_ShowInList, show_in_list );
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_MemberTitle, DB_GROUP_TITLE_BUF_SIZE, member_title );
- msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_InsigniaID, insignia_id );
- msg->getU64Fast(_PREHASH_GroupData, _PREHASH_PowersMask, powers_mask );
- msg->getU32Fast(_PREHASH_GroupData, _PREHASH_MembershipFee, membership_fee );
- msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_OpenEnrollment, open_enrollment );
- msg->getS32Fast(_PREHASH_GroupData, _PREHASH_GroupMembershipCount, num_group_members);
- msg->getS32(_PREHASH_GroupData, "GroupRolesCount", num_group_roles);
- msg->getS32Fast(_PREHASH_GroupData, _PREHASH_Money, money);
+ msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_FounderID, founder_id);
+ msg->getStringFast(_PREHASH_GroupData, _PREHASH_Name, name );
+ msg->getStringFast(_PREHASH_GroupData, _PREHASH_Charter, charter );
+ msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_ShowInList, show_in_list );
+ msg->getStringFast(_PREHASH_GroupData, _PREHASH_MemberTitle, member_title );
+ msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_InsigniaID, insignia_id );
+ msg->getU64Fast(_PREHASH_GroupData, _PREHASH_PowersMask, powers_mask );
+ msg->getU32Fast(_PREHASH_GroupData, _PREHASH_MembershipFee, membership_fee );
+ msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_OpenEnrollment, open_enrollment );
+ msg->getS32Fast(_PREHASH_GroupData, _PREHASH_GroupMembershipCount, num_group_members);
+ msg->getS32(_PREHASH_GroupData, "GroupRolesCount", num_group_roles);
+ msg->getS32Fast(_PREHASH_GroupData, _PREHASH_Money, money);
msg->getBOOL("GroupData", "AllowPublish", allow_publish);
msg->getBOOL("GroupData", "MaturePublish", mature);
msg->getUUID(_PREHASH_GroupData, "OwnerRole", owner_role);
- LLGroupMgrGroupData* group_datap = gGroupMgr->createGroupData(group_id);
+ LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->createGroupData(group_id);
group_datap->mName = name;
group_datap->mCharter = charter;
@@ -951,7 +1016,7 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
group_datap->mGroupPropertiesDataComplete = TRUE;
group_datap->mChanged = TRUE;
- gGroupMgr->notifyObservers(GC_PROPERTIES);
+ LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES);
}
// static
@@ -972,7 +1037,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
LLUUID request_id;
msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_RequestID, request_id);
- LLGroupMgrGroupData* group_data = gGroupMgr->createGroupData(group_id);
+ LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->createGroupData(group_id);
if (group_data->mRoleDataRequestID != request_id)
{
llwarns << "processGroupRoleDataReply: Received incorrect (stale?) request id" << llendl;
@@ -981,9 +1046,9 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
msg->getS32(_PREHASH_GroupData, "RoleCount", group_data->mRoleCount );
- char name[DB_GROUP_NAME_BUF_SIZE]; /* Flawfinder: ignore */
- char title[DB_GROUP_TITLE_BUF_SIZE]; /* Flawfinder: ignore */
- char desc[DB_GROUP_CHARTER_BUF_SIZE]; /* Flawfinder: ignore */
+ std::string name;
+ std::string title;
+ std::string desc;
U64 powers = 0;
U32 member_count = 0;
LLUUID role_id;
@@ -994,12 +1059,30 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
{
msg->getUUID("RoleData", "RoleID", role_id, i );
- msg->getString("RoleData","Name",DB_GROUP_NAME_BUF_SIZE,name,i);
- msg->getString("RoleData","Title",DB_GROUP_TITLE_BUF_SIZE,title,i);
- msg->getString("RoleData","Description",DB_GROUP_CHARTER_BUF_SIZE,desc,i);
+ msg->getString("RoleData","Name",name,i);
+ msg->getString("RoleData","Title",title,i);
+ msg->getString("RoleData","Description",desc,i);
msg->getU64("RoleData","Powers",powers,i);
msg->getU32("RoleData","Members",member_count,i);
+ //there are 3 predifined roles - Owners, Officers, Everyone
+ //there names are defined in lldatagroups.cpp
+ //lets change names from server to localized strings
+ if(name == "Everyone")
+ {
+ name = LLTrans::getString("group_role_everyone");
+ }
+ else if(name == "Officers")
+ {
+ name = LLTrans::getString("group_role_officers");
+ }
+ else if(name == "Owners")
+ {
+ name = LLTrans::getString("group_role_owners");
+ }
+
+
+
lldebugs << "Adding role data: " << name << " {" << role_id << "}" << llendl;
LLGroupRoleData* rd = new LLGroupRoleData(role_id,name,title,desc,powers,member_count);
group_data->mRoles[role_id] = rd;
@@ -1013,12 +1096,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
if (group_data->mPendingRoleMemberRequest)
{
group_data->mPendingRoleMemberRequest = FALSE;
- gGroupMgr->sendGroupRoleMembersRequest(group_data->mID);
+ LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_data->mID);
}
}
group_data->mChanged = TRUE;
- gGroupMgr->notifyObservers(GC_ROLE_DATA);
+ LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA);
}
// static
@@ -1042,7 +1125,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
U32 total_pairs;
msg->getU32(_PREHASH_AgentData, "TotalPairs", total_pairs);
- LLGroupMgrGroupData* group_data = gGroupMgr->createGroupData(group_id);
+ LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->createGroupData(group_id);
if (group_data->mRoleMembersRequestID != request_id)
{
@@ -1092,8 +1175,8 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
}
else
{
- if (!rd) llwarns << "Received role data for unkown role " << role_id << " in group " << group_id << llendl;
- if (!md) llwarns << "Received role data for unkown member " << member_id << " in group " << group_id << llendl;
+ if (!rd) llwarns << "Received role data for unknown role " << role_id << " in group " << group_id << llendl;
+ if (!md) llwarns << "Received role data for unknown member " << member_id << " in group " << group_id << llendl;
}
}
}
@@ -1127,7 +1210,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
}
group_data->mChanged = TRUE;
- gGroupMgr->notifyObservers(GC_ROLE_MEMBER_DATA);
+ LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_MEMBER_DATA);
}
// static
@@ -1145,7 +1228,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
LLUUID group_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
- LLGroupMgrGroupData* group_data = gGroupMgr->createGroupData(group_id);
+ LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->createGroupData(group_id);
LLUUID request_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_RequestID, request_id);
@@ -1156,20 +1239,17 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
return;
}
- char title_buf[DB_GROUP_TITLE_BUF_SIZE]; /* Flawfinder: ignore */
-
LLGroupTitle title;
S32 i = 0;
S32 blocks = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
for (i=0; i<blocks; ++i)
{
- msg->getString("GroupData","Title",DB_GROUP_TITLE_BUF_SIZE,title_buf,i);
- title.mTitle = title_buf;
+ msg->getString("GroupData","Title",title.mTitle,i);
msg->getUUID("GroupData","RoleID",title.mRoleID,i);
msg->getBOOL("GroupData","Selected",title.mSelected,i);
- if (title_buf[0] != '\0')
+ if (!title.mTitle.empty())
{
lldebugs << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << llendl;
group_data->mTitles.push_back(title);
@@ -1177,7 +1257,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
}
group_data->mChanged = TRUE;
- gGroupMgr->notifyObservers(GC_TITLES);
+ LLGroupMgr::getInstance()->notifyObservers(GC_TITLES);
}
// static
@@ -1192,7 +1272,7 @@ void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data
// If we had a failure, the group panel needs to be updated.
if (!success)
{
- LLFloaterGroupInfo::refreshGroup(group_id);
+ LLGroupActions::refresh(group_id);
}
}
@@ -1210,11 +1290,9 @@ void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data)
// refresh all group information
gAgent.sendAgentDataUpdateRequest();
- gGroupMgr->clearGroupData(group_id);
+ LLGroupMgr::getInstance()->clearGroupData(group_id);
// refresh the floater for this group, if any.
- LLFloaterGroupInfo::refreshGroup(group_id);
- // refresh the group panel of the search window, if necessary.
- LLFloaterDirectory::refreshGroup(group_id);
+ LLGroupActions::refresh(group_id);
}
}
@@ -1232,11 +1310,9 @@ void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data)
// refresh all group information
gAgent.sendAgentDataUpdateRequest();
- gGroupMgr->clearGroupData(group_id);
+ LLGroupMgr::getInstance()->clearGroupData(group_id);
// close the floater for this group, if any.
- LLFloaterGroupInfo::closeGroup(group_id);
- // refresh the group panel of the search window, if necessary.
- LLFloaterDirectory::refreshGroup(group_id);
+ LLGroupActions::closeGroup(group_id);
}
}
@@ -1245,12 +1321,12 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
{
LLUUID group_id;
BOOL success;
- char message[MAX_STRING]; /* Flawfinder: ignore */
+ std::string message;
msg->getUUIDFast(_PREHASH_ReplyData, _PREHASH_GroupID, group_id );
msg->getBOOLFast(_PREHASH_ReplyData, _PREHASH_Success, success );
- msg->getStringFast(_PREHASH_ReplyData, _PREHASH_Message, MAX_STRING, message );
+ msg->getStringFast(_PREHASH_ReplyData, _PREHASH_Message, message );
if (success)
{
@@ -1270,15 +1346,17 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
gAgent.mGroups.push_back(gd);
- LLFloaterGroupInfo::closeCreateGroup();
- LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab");
+ LLPanelGroup::refreshCreatedGroup(group_id);
+ //FIXME
+ //LLFloaterGroupInfo::closeCreateGroup();
+ //LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab");
}
else
{
- // *TODO:translate
- LLString::format_map_t args;
- args["[MESSAGE]"] = message;
- gViewerWindow->alertXml("UnableToCreateGroup", args);
+ // *TODO: Translate
+ LLSD args;
+ args["MESSAGE"] = message;
+ LLNotificationsUtil::add("UnableToCreateGroup", args);
}
}
@@ -1286,11 +1364,11 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id)
{
LLGroupMgrGroupData* group_datap;
- group_map_t::iterator existing_group = gGroupMgr->mGroups.find(id);
- if (existing_group == gGroupMgr->mGroups.end())
+ group_map_t::iterator existing_group = LLGroupMgr::getInstance()->mGroups.find(id);
+ if (existing_group == LLGroupMgr::getInstance()->mGroups.end())
{
group_datap = new LLGroupMgrGroupData(id);
- gGroupMgr->addGroup(group_datap);
+ LLGroupMgr::getInstance()->addGroup(group_datap);
}
else
{
@@ -1304,15 +1382,33 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc)
{
for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi)
{
+ LLUUID group_id = gi->first;
if (gi->second->mChanged)
{
+ // notify LLGroupMgrObserver
+ // Copy the map because observers may remove themselves on update
+ observer_multimap_t observers = mObservers;
+
// find all observers for this group id
- observer_multimap_t::iterator oi = mObservers.find(gi->first);
- for (; oi != mObservers.end(); ++oi)
+ observer_multimap_t::iterator oi = observers.lower_bound(group_id);
+ observer_multimap_t::iterator end = observers.upper_bound(group_id);
+ for (; oi != end; ++oi)
{
oi->second->changed(gc);
}
gi->second->mChanged = FALSE;
+
+
+ // notify LLParticularGroupObserver
+ observer_map_t::iterator obs_it = mParticularObservers.find(group_id);
+ if(obs_it == mParticularObservers.end())
+ return;
+
+ observer_set_t& obs = obs_it->second;
+ for (observer_set_t::iterator ob_it = obs.begin(); ob_it != obs.end(); ++ob_it)
+ {
+ (*ob_it)->changed(group_id, gc);
+ }
}
}
}
@@ -1642,22 +1738,26 @@ void LLGroupMgr::sendGroupMemberInvites(const LLUUID& group_id, std::map<LLUUID,
//static
void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
- std::vector<LLUUID>& member_ids)
+ uuid_vec_t& member_ids)
{
bool start_message = true;
LLMessageSystem* msg = gMessageSystem;
- LLGroupMgrGroupData* group_datap = gGroupMgr->getGroupData(group_id);
+
+
+ LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
if (!group_datap) return;
- for (std::vector<LLUUID>::iterator it = member_ids.begin();
+ for (uuid_vec_t::iterator it = member_ids.begin();
it != member_ids.end(); ++it)
{
+ LLUUID& ejected_member_id = (*it);
+
// Can't use 'eject' to leave a group.
- if ((*it) == gAgent.getID()) continue;
+ if (ejected_member_id == gAgent.getID()) continue;
// Make sure they are in the group, and we need the member data
- LLGroupMgrGroupData::member_list_t::iterator mit = group_datap->mMembers.find(*it);
+ LLGroupMgrGroupData::member_list_t::iterator mit = group_datap->mMembers.find(ejected_member_id);
if (mit != group_datap->mMembers.end())
{
// Add them to the message
@@ -1673,7 +1773,7 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
}
msg->nextBlock("EjectData");
- msg->addUUID("EjecteeID",(*it));
+ msg->addUUID("EjecteeID",ejected_member_id);
if (msg->isSendFull())
{
@@ -1681,17 +1781,23 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
start_message = true;
}
+ LLGroupMemberData* member_data = (*mit).second;
+
// Clean up groupmgr
- for (LLGroupMemberData::role_list_t::iterator rit = (*mit).second->roleBegin();
- rit != (*mit).second->roleEnd(); ++rit)
+ for (LLGroupMemberData::role_list_t::iterator rit = member_data->roleBegin();
+ rit != member_data->roleEnd(); ++rit)
{
- if ((*rit).first.notNull())
+ if ((*rit).first.notNull() && (*rit).second!=0)
{
- (*rit).second->removeMember(*it);
+ (*rit).second->removeMember(ejected_member_id);
}
}
- delete (*mit).second;
- group_datap->mMembers.erase(*it);
+
+ group_datap->mMembers.erase(ejected_member_id);
+
+ // member_data was introduced and is used here instead of (*mit).second to avoid crash because of invalid iterator
+ // It becomes invalid after line with erase above. EXT-4778
+ delete member_data;
}
}
@@ -1725,7 +1831,7 @@ void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id)
}
//static
-bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
+bool LLGroupMgr::parseRoleActions(const std::string& xml_filename)
{
LLXMLNodePtr root;
@@ -1749,7 +1855,7 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
LLRoleAction* role_action_data = new LLRoleAction();
// name=
- LLString action_set_name;
+ std::string action_set_name;
if (action_set->getAttributeString("name", action_set_name))
{
lldebugs << "Loading action set " << action_set_name << llendl;
@@ -1763,13 +1869,13 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
continue;
}
// description=
- LLString set_description;
+ std::string set_description;
if (action_set->getAttributeString("description", set_description))
{
role_action_data->mDescription = set_description;
}
// long description=
- LLString set_longdescription;
+ std::string set_longdescription;
if (action_set->getAttributeString("longdescription", set_longdescription))
{
role_action_data->mLongDescription = set_longdescription;
@@ -1790,7 +1896,7 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
LLRoleAction* role_action = new LLRoleAction();
// name=
- LLString action_name;
+ std::string action_name;
if (action->getAttributeString("name", action_name))
{
lldebugs << "Loading action " << action_name << llendl;
@@ -1803,13 +1909,13 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
continue;
}
// description=
- LLString description;
+ std::string description;
if (action->getAttributeString("description", description))
{
role_action->mDescription = description;
}
// long description=
- LLString longdescription;
+ std::string longdescription;
if (action->getAttributeString("longdescription", longdescription))
{
role_action->mLongDescription = longdescription;
@@ -1832,7 +1938,7 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
role_action_data->mPowerBit = set_power_mask;
role_action_set->mActionSetData = role_action_data;
- gGroupMgr->mRoleActionSets.push_back(role_action_set);
+ LLGroupMgr::getInstance()->mRoleActionSets.push_back(role_action_set);
}
return true;
}
@@ -1840,7 +1946,7 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
// static
void LLGroupMgr::debugClearAllGroups(void*)
{
- gGroupMgr->clearGroups();
+ LLGroupMgr::getInstance()->clearGroups();
LLGroupMgr::parseRoleActions("role_actions.xml");
}