From 4945ae17d3692f089ce6c996f6585a5e5b308e4d Mon Sep 17 00:00:00 2001 From: Baker Linden Date: Thu, 29 Aug 2013 11:36:45 -0700 Subject: Initial commit for GroupBan - Lots of crap isn't working as intended yet. --- indra/newview/llpanelgroupbulk.cpp | 403 +++++++++++++++++++++++++++++++++++++ 1 file changed, 403 insertions(+) create mode 100644 indra/newview/llpanelgroupbulk.cpp (limited to 'indra/newview/llpanelgroupbulk.cpp') 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("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 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 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 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 selection = mBulkAgentList->getAllSelected(); + if (selection.empty()) + mRemoveButton->setEnabled(FALSE); + else + mRemoveButton->setEnabled(TRUE); +} + +void LLPanelGroupBulkImpl::addUsers(const std::vector& 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 items = mBulkAgentList->getAllData(); + std::vector::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 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 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); +} + -- cgit v1.2.3 From 34f561db55868185f0a946009f41f4f212366484 Mon Sep 17 00:00:00 2001 From: Baker Linden Date: Fri, 13 Sep 2013 17:20:04 -0700 Subject: - Added ban date to ban list ui - Code cleanup --- indra/newview/llpanelgroupbulk.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/newview/llpanelgroupbulk.cpp') diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 6c6fd8cfe0..ed05a5c7d1 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -294,7 +294,10 @@ void LLPanelGroupBulk::updateGroupData() { LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mImplementation->mGroupID << LL_ENDL; return; + } if(gdatap->isGroupPropertiesDataComplete()) mPendingGroupPropertiesUpdate = false; -- cgit v1.2.3 From 8bf4760552b61808d403885b6f9d562b1b8f7e6c Mon Sep 17 00:00:00 2001 From: Baker Linden Date: Tue, 1 Oct 2013 15:58:39 -0700 Subject: Hand-merge of some viewer-release code --- indra/newview/llpanelgroupbulk.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'indra/newview/llpanelgroupbulk.cpp') diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index ed05a5c7d1..86ac1867df 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -172,6 +172,12 @@ void LLPanelGroupBulkImpl::handleRemove() if (selection.empty()) return; + std::vector::iterator iter; + for(iter = selection.begin(); iter != selection.end(); ++iter) + { + mInviteeIDs.erase((*iter)->getUUID()); + } + mBulkAgentList->deleteSelectedItems(); mRemoveButton->setEnabled(FALSE); @@ -195,26 +201,23 @@ void LLPanelGroupBulkImpl::addUsers(const std::vector& names, const { std::string name; LLUUID id; + + if(names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES) + { + // Fail! Show a warning and don't add any names. + LLSD msg; + msg["MESSAGE"] = mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + return; + } + for (S32 i = 0; i < (S32)names.size(); ++i) { name = names[i]; id = agent_ids[i]; - // Make sure this agent isn't already in the list. - bool already_in_list = false; - std::vector items = mBulkAgentList->getAllData(); - std::vector::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) + if(mInviteeIDs.find(id) != mInviteeIDs.end()) { continue; } @@ -225,7 +228,8 @@ void LLPanelGroupBulkImpl::addUsers(const std::vector& names, const row["columns"][0]["value"] = name; mBulkAgentList->addElement(row); - + mInviteeIDs.insert(id); + // We've successfully added someone to the list. if(mOKButton && !mOKButton->getEnabled()) mOKButton->setEnabled(TRUE); @@ -254,6 +258,8 @@ LLPanelGroupBulk::~LLPanelGroupBulk() void LLPanelGroupBulk::clear() { + mImplementation->mInviteeIDs.clear(); + if(mImplementation->mBulkAgentList) mImplementation->mBulkAgentList->deleteAllItems(); -- cgit v1.2.3 From 29ef25f7ba0cfe229d7b91eb8481f6ef1eeb6f8e Mon Sep 17 00:00:00 2001 From: Baker Linden Date: Fri, 4 Apr 2014 12:30:01 -0700 Subject: [GroupBan] [MAINT-3810] Viewer crash when inviting nearby agents via right click - Fixed an issue where residents would be unable to be invited to a group. - Fixed a crash when trying to invite a resident to a group via right-click menu --- indra/newview/llpanelgroupbulk.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'indra/newview/llpanelgroupbulk.cpp') diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 86ac1867df..9d02b9b45a 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -299,14 +299,10 @@ void LLPanelGroupBulk::updateGroupName() void LLPanelGroupBulk::updateGroupData() { LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); - if(!gdatap) + if(gdatap && gdatap->isGroupPropertiesDataComplete()) { - LL_WARNS("Groups") << "Unable to get group data for group " << mImplementation->mGroupID << LL_ENDL; - return; - } - - if(gdatap->isGroupPropertiesDataComplete()) mPendingGroupPropertiesUpdate = false; + } else { if(!mPendingGroupPropertiesUpdate) @@ -316,8 +312,10 @@ void LLPanelGroupBulk::updateGroupData() } } - if(gdatap->isRoleDataComplete()) + if(gdatap && gdatap->isRoleDataComplete()) + { mPendingRoleDataUpdate = false; + } else { if(!mPendingRoleDataUpdate) @@ -327,8 +325,10 @@ void LLPanelGroupBulk::updateGroupData() } } - if(gdatap->isMemberDataComplete()) + if(gdatap && gdatap->isMemberDataComplete()) + { mPendingMemberDataUpdate = false; + } else { if(!mPendingMemberDataUpdate) -- cgit v1.2.3 From bfc274741ad97a2885a26ae35108e158aeb9525e Mon Sep 17 00:00:00 2001 From: Baker Linden Date: Tue, 6 May 2014 11:01:59 -0700 Subject: [MAINT-3834] Banning more than 100 residents causes multiple floaters - Removed superfluous floater dialogs from displaying Reviewer: Simon --- indra/newview/llpanelgroupbulk.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'indra/newview/llpanelgroupbulk.cpp') diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 9d02b9b45a..1eafc5bd64 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -66,7 +66,8 @@ LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : mRoleNames(NULL), mOwnerWarning(), mAlreadyInGroup(), - mConfirmedOwnerInvite(false) + mConfirmedOwnerInvite(false), + mListFullNotificationSent(false) {} LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() @@ -201,17 +202,24 @@ void LLPanelGroupBulkImpl::addUsers(const std::vector& names, const { std::string name; LLUUID id; - - if(names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES) + if(mListFullNotificationSent) + { + return; + } + + if( !mListFullNotificationSent && + (names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES)) { + mListFullNotificationSent = true; + // Fail! Show a warning and don't add any names. LLSD msg; msg["MESSAGE"] = mTooManySelected; LLNotificationsUtil::add("GenericAlert", msg); return; } - + for (S32 i = 0; i < (S32)names.size(); ++i) { name = names[i]; @@ -407,6 +415,7 @@ void LLPanelGroupBulk::addUsers(uuid_vec_t& agent_ids) } } } + mImplementation->mListFullNotificationSent = false; mImplementation->addUsers(names, agent_ids); } -- cgit v1.2.3