diff options
Diffstat (limited to 'indra/newview/llgroupmgr.cpp')
-rw-r--r-- | indra/newview/llgroupmgr.cpp | 346 |
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"); } |