From 162cf8240158d2d487d014bdac77f58a8c75595f Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Thu, 16 Sep 2010 06:08:15 -0700 Subject: Added search bars for friends and groups lists, based on a feature in the Ascent viewer by Charley Levenque --- linden/indra/newview/llcallingcard.cpp | 5 +++ linden/indra/newview/llcallingcard.h | 3 ++ linden/indra/newview/llfloaterfriends.cpp | 52 ++++++++++++++++++++++ linden/indra/newview/llfloaterfriends.h | 4 +- linden/indra/newview/llfloatergroups.cpp | 52 +++++++++++++++++++++- linden/indra/newview/llfloatergroups.h | 3 +- .../skins/default/xui/en-us/panel_friends.xml | 39 ++++++++-------- .../skins/default/xui/en-us/panel_groups.xml | 7 ++- 8 files changed, 142 insertions(+), 23 deletions(-) diff --git a/linden/indra/newview/llcallingcard.cpp b/linden/indra/newview/llcallingcard.cpp index db28c7a..155fb60 100644 --- a/linden/indra/newview/llcallingcard.cpp +++ b/linden/indra/newview/llcallingcard.cpp @@ -357,6 +357,11 @@ void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online) } } +S32 LLAvatarTracker::getBuddyCount() +{ + return mBuddyInfo.size(); +} + bool LLAvatarTracker::isBuddyOnline(const LLUUID& id) const { LLRelationship* info = get_ptr_in_map(mBuddyInfo, id); diff --git a/linden/indra/newview/llcallingcard.h b/linden/indra/newview/llcallingcard.h index 85a1ab6..0db5376 100644 --- a/linden/indra/newview/llcallingcard.h +++ b/linden/indra/newview/llcallingcard.h @@ -129,6 +129,9 @@ public: void setBuddyOnline(const LLUUID& id, bool is_online); bool isBuddyOnline(const LLUUID& id) const; + // get count of buddies + S32 getBuddyCount(); + // simple empowered status void setBuddyEmpowered(const LLUUID& id, bool is_empowered); bool isBuddyEmpowered(const LLUUID& id) const; diff --git a/linden/indra/newview/llfloaterfriends.cpp b/linden/indra/newview/llfloaterfriends.cpp index e18e705..479da89 100644 --- a/linden/indra/newview/llfloaterfriends.cpp +++ b/linden/indra/newview/llfloaterfriends.cpp @@ -183,6 +183,52 @@ void LLPanelFriends::updateFriends(U32 changed_mask) mShowMaxSelectWarning = true; } +void LLPanelFriends::filterContacts(const std::string& search_string) +{ + std::string search = search_string; + LLStringUtil::toLower(search); + + if (search.empty()) + { + // repopulate + refreshNames(LLFriendObserver::ADD); + } + else + { + // just in case someone else emptied us, tsk + if (mFriendsList->isEmpty() && LLAvatarTracker::instance().getBuddyCount() > 0) + { + refreshNames(LLFriendObserver::ADD); + } + + // don't worry about maintaining selection since we're searching + std::vector vFriends(mFriendsList->getAllData()); + + // this should really REALLY use deleteAllItems() to rebuild the list instead + std::string friend_name; + for (std::vector::iterator itr = vFriends.begin(); itr != vFriends.end(); ++itr) + { + friend_name = (*itr)->getColumn(LIST_FRIEND_NAME)->getValue().asString(); + LLStringUtil::toLower(friend_name); + BOOL show_entry = (friend_name.find(search) != std::string::npos); + if (!show_entry) + { + mFriendsList->deleteItems((*itr)->getValue()); + } + } + } + refreshUI(); +} + +void LLPanelFriends::onContactSearchKeystroke(const std::string& search_string, void* user_data) +{ + LLPanelFriends* panelp = (LLPanelFriends*)user_data; + if (panelp) + { + panelp->filterContacts(search_string); + } +} + // virtual BOOL LLPanelFriends::postBuild() { @@ -193,6 +239,12 @@ BOOL LLPanelFriends::postBuild() childSetCommitCallback("friend_list", onSelectName, this); childSetDoubleClickCallback("friend_list", onClickIM); + LLSearchEditor* buddy_search = getChild("buddy_search"); + if (buddy_search) + { + buddy_search->setSearchCallback(&onContactSearchKeystroke, this); + } + U32 changed_mask = LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE; refreshNames(changed_mask); diff --git a/linden/indra/newview/llfloaterfriends.h b/linden/indra/newview/llfloaterfriends.h index f7f0b32..9a1feba 100644 --- a/linden/indra/newview/llfloaterfriends.h +++ b/linden/indra/newview/llfloaterfriends.h @@ -101,6 +101,8 @@ private: // protected members typedef std::map rights_map_t; void refreshNames(U32 changed_mask); + void filterContacts(const std::string& search_string); + BOOL refreshNamesSync(const LLAvatarTracker::buddy_map_t & all_buddies); BOOL refreshNamesPresence(const LLAvatarTracker::buddy_map_t & all_buddies); void refreshUI(); @@ -126,7 +128,7 @@ private: static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); static void onPickAvatar(const std::vector& names, const std::vector& ids, void* user_data); static void onMaximumSelect(void* user_data); - + static void onContactSearchKeystroke(const std::string& search_string, void* user_data); static void onClickIM(void* user_data); static void onClickProfile(void* user_data); static void onClickAddFriend(void* user_data); diff --git a/linden/indra/newview/llfloatergroups.cpp b/linden/indra/newview/llfloatergroups.cpp index daf1709..b3fbb1b 100644 --- a/linden/indra/newview/llfloatergroups.cpp +++ b/linden/indra/newview/llfloatergroups.cpp @@ -214,6 +214,12 @@ BOOL LLPanelGroups::postBuild() { childSetCommitCallback("group list", onGroupList, this); + LLSearchEditor* group_search = getChild("group_search"); + if (group_search) + { + group_search->setSearchCallback(&onGroupSearchKeystroke, this); + } + childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); @@ -379,7 +385,7 @@ void LLPanelGroups::info() void LLPanelGroups::startIM() { - //llinfos << "LLPanelFriends::onClickIM()" << llendl; + //llinfos << "LLPanelGroups::onClickIM()" << llendl; LLCtrlListInterface *group_list = childGetListInterface("group list"); LLUUID group_id; @@ -612,3 +618,47 @@ void LLPanelGroups::applyChangesToGroups() } } } + +void LLPanelGroups::filterContacts(const std::string& search_string) +{ + std::string search = search_string; + LLStringUtil::toLower(search); + + if (search.empty()) + { + // repopulate + reset(); + } + else + { + LLScrollListCtrl* group_list = getChild("group list"); + if (group_list) + { + // don't worry about maintaining selection since we're searching + std::vector vGroups(group_list->getAllData()); + + // this should really REALLY use deleteAllItems() to rebuild the list instead + std::string group_name; + for (std::vector::iterator itr = vGroups.begin(); itr != vGroups.end(); ++itr) + { + group_name = (*itr)->getColumn(0)->getValue().asString(); + LLStringUtil::toLower(group_name); + BOOL show_entry = (group_name.find(search) != std::string::npos); + if (!show_entry) + { + group_list->deleteItems((*itr)->getValue()); + } + } + enableButtons(); + } + } +} + +void LLPanelGroups::onGroupSearchKeystroke(const std::string& search_string, void* user_data) +{ + LLPanelGroups* panelp = (LLPanelGroups*)user_data; + if (panelp) + { + panelp->filterContacts(search_string); + } +} diff --git a/linden/indra/newview/llfloatergroups.h b/linden/indra/newview/llfloatergroups.h index 91021f0..5dc7ad8 100644 --- a/linden/indra/newview/llfloatergroups.h +++ b/linden/indra/newview/llfloatergroups.h @@ -115,6 +115,7 @@ protected: static void onBtnInvite(void* userdata); static void onBtnTitles(void* userdata); static void onDoubleClickGroup(void* userdata); + static void onGroupSearchKeystroke(const std::string& search_string, void* user_data); void create(); void activate(); @@ -125,9 +126,9 @@ protected: void callVote(); void invite(); void titles(); + void filterContacts(const std::string& search_string); static bool callbackLeaveGroup(const LLSD& notification, const LLSD& response); - }; diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_friends.xml b/linden/indra/newview/skins/default/xui/en-us/panel_friends.xml index 0854c99..a64560f 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_friends.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_friends.xml @@ -3,43 +3,46 @@ Multiple friends... - - + - - + - - - - - - - -