summaryrefslogtreecommitdiff
path: root/indra/newview/llpanelpeople.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpanelpeople.cpp')
-rw-r--r--indra/newview/llpanelpeople.cpp300
1 files changed, 189 insertions, 111 deletions
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 1d7a2748cc..92a8653252 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -35,7 +35,7 @@
// libs
#include "llfloaterreg.h"
#include "llmenugl.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
#include "lltabcontainer.h"
#include "lluictrlfactory.h"
@@ -47,7 +47,7 @@
#include "llcallingcard.h" // for LLAvatarTracker
#include "llfloateravatarpicker.h"
#include "llfloaterminiinspector.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
#include "llgroupactions.h"
#include "llgrouplist.h"
#include "llrecentpeople.h"
@@ -62,10 +62,18 @@ using namespace LLOldEvents;
#define NEARBY_LIST_UPDATE_INTERVAL 1
#define RECENT_LIST_UPDATE_DELAY 1
+static const std::string NEARBY_TAB_NAME = "nearby_panel";
+static const std::string FRIENDS_TAB_NAME = "friends_panel";
+static const std::string GROUP_TAB_NAME = "groups_panel";
+static const std::string RECENT_TAB_NAME = "recent_panel";
+
static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
//=============================================================================
+/**
+ * Updates given list either on regular basis or on external events (up to implementation).
+ */
class LLPanelPeople::Updater
{
public:
@@ -74,15 +82,31 @@ public:
: mCallback(cb)
{
}
+
virtual ~Updater()
{
}
+
+ /**
+ * Force the list updates.
+ *
+ * This may start repeated updates until all names are complete.
+ */
+ virtual void forceUpdate() {}
+
+ /**
+ * Activate/deactivate updater.
+ *
+ * This may start/stop regular updates.
+ */
virtual void setActive(bool) {}
+
protected:
bool updateList(U32 mask = 0)
{
return mCallback(mask);
}
+
callback_t mCallback;
};
@@ -99,10 +123,13 @@ public:
/**
* Updates the friends list.
+ *
+ * Updates the list on external events which trigger the changed() method.
*/
class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
{
LOG_CLASS(LLFriendListUpdater);
+
public:
LLFriendListUpdater(callback_t cb)
: LLAvatarListUpdater(cb, FRIEND_LIST_UPDATE_TIMEOUT)
@@ -111,20 +138,20 @@ public:
// For notification when SIP online status changes.
LLVoiceClient::getInstance()->addObserver(this);
}
+
~LLFriendListUpdater()
{
LLVoiceClient::getInstance()->removeObserver(this);
LLAvatarTracker::instance().removeObserver(this);
}
- /*virtual*/ void setActive(bool val)
- {
- if (!val)
- return;
+ /*virtual*/ void forceUpdate()
+ {
// Perform updates until all names are loaded.
if (!updateList(LLFriendObserver::ADD))
changed(LLFriendObserver::ADD);
}
+
/*virtual*/ void changed(U32 mask)
{
// events can arrive quickly in bulk - we need not process EVERY one of them -
@@ -134,6 +161,7 @@ public:
// save-up all the mask-bits which have come-in
mMask |= mask;
}
+
/*virtual*/ BOOL tick()
{
if (updateList(mMask))
@@ -145,33 +173,33 @@ public:
return FALSE;
}
+
private:
U32 mMask;
};
/**
* Periodically updates the nearby people list while the Nearby tab is active.
+ *
+ * The period is defined by NEARBY_LIST_UPDATE_INTERVAL constant.
*/
class LLNearbyListUpdater : public LLAvatarListUpdater
{
LOG_CLASS(LLNearbyListUpdater);
+
public:
LLNearbyListUpdater(callback_t cb)
: LLAvatarListUpdater(cb, NEARBY_LIST_UPDATE_INTERVAL)
{
setActive(false);
}
- /*virtual*/ BOOL tick()
- {
- updateList();
- return FALSE;
- }
+
/*virtual*/ void setActive(bool val)
{
if (val)
{
// update immediately and start regular updates
- tick();
+ updateList();
mEventTimer.start();
}
else
@@ -180,6 +208,17 @@ public:
mEventTimer.stop();
}
}
+
+ /*virtual*/ void forceUpdate()
+ {
+ updateList();
+ }
+
+ /*virtual*/ BOOL tick()
+ {
+ updateList();
+ return FALSE;
+ }
private:
};
@@ -189,13 +228,20 @@ private:
class LLRecentListUpdater : public LLAvatarListUpdater
{
LOG_CLASS(LLRecentListUpdater);
+
public:
LLRecentListUpdater(callback_t cb)
: LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
{
LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this));
}
+
private:
+ /*virtual*/ void forceUpdate()
+ {
+ onRecentPeopleChanged();
+ }
+
/*virtual*/ BOOL tick()
{
// Update the list until we get all the names.
@@ -207,6 +253,7 @@ private:
return FALSE;
}
+
void onRecentPeopleChanged()
{
if (!updateList())
@@ -223,16 +270,24 @@ private:
class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener
{
LOG_CLASS(LLGroupListUpdater);
+
public:
LLGroupListUpdater(callback_t cb)
: LLPanelPeople::Updater(cb)
{
gAgent.addListener(this, "new group");
}
+
~LLGroupListUpdater()
{
gAgent.removeListener(this);
}
+
+ /*virtual*/ void forceUpdate()
+ {
+ updateList();
+ }
+
/*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
// Why is "new group" sufficient?
@@ -251,7 +306,7 @@ public:
LLPanelPeople::LLPanelPeople()
: LLPanel(),
mFilterSubString(LLStringUtil::null),
- mSearchEditor(NULL),
+ mFilterEditor(NULL),
mTabContainer(NULL),
mFriendList(NULL),
mNearbyList(NULL),
@@ -271,28 +326,28 @@ LLPanelPeople::~LLPanelPeople()
delete mGroupListUpdater;
LLView::deleteViewByHandle(mGroupPlusMenuHandle);
- LLView::deleteViewByHandle(mGroupMinusMenuHandle);
}
BOOL LLPanelPeople::postBuild()
{
- mSearchEditor = getChild<LLSearchEditor>("filter_input");
+ mFilterEditor = getChild<LLFilterEditor>("filter_input");
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
mTabContainer = getChild<LLTabContainer>("tabs");
mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
- mTabContainer->selectTabByName("friends_panel"); // must go after setting commit callback
+ mTabContainer->selectTabByName(FRIENDS_TAB_NAME); // must go after setting commit callback
- mFriendList = getChild<LLPanel>("friends_panel")->getChild<LLAvatarList>("avatar_list");
- mNearbyList = getChild<LLPanel>("nearby_panel")->getChild<LLAvatarList>("avatar_list");
- mRecentList = getChild<LLPanel>("recent_panel")->getChild<LLAvatarList>("avatar_list");
+ mFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+ mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+ mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
mGroupList = getChild<LLGroupList>("group_list");
- LLPanel* groups_panel = getChild<LLPanel>("groups_panel");
+ LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this));
groups_panel->childSetAction("plus_btn", boost::bind(&LLPanelPeople::onGroupPlusButtonClicked, this));
groups_panel->childSetAction("minus_btn", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this));
- LLPanel* friends_panel = getChild<LLPanel>("friends_panel");
+ LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME);
friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this));
friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this));
@@ -319,89 +374,95 @@ BOOL LLPanelPeople::postBuild()
// Create menus.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2));
- LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder);
+ LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mGroupPlusMenuHandle = plus_menu->getHandle();
- registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusMenuItemClicked, this, _2));
- LLMenuGL* minus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_minus.xml", gMenuHolder);
- mGroupMinusMenuHandle = minus_menu->getHandle();
// Perform initial update.
- mFriendListUpdater->setActive(true);
+ mFriendListUpdater->forceUpdate();
updateGroupList();
updateRecentList();
return TRUE;
}
-bool LLPanelPeople::refreshFriendNames(U32 changed_mask)
+bool LLPanelPeople::updateFriendList(U32 changed_mask)
{
- // get all buddies we know about
- LLAvatarTracker::buddy_map_t all_buddies;
- LLAvatarTracker::instance().copyBuddyList(all_buddies);
-
- bool have_names = true;
-
+ // Refresh names.
if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
{
+ // get all buddies we know about
+ LLAvatarTracker::buddy_map_t all_buddies;
+ LLAvatarTracker::instance().copyBuddyList(all_buddies);
+
// *TODO: it's suboptimal to rebuild the whole list on online status change.
// convert the buddy map to vector
- std::vector<LLUUID> avatar_ids;
+ mFriendVec.clear();
LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
for (; buddy_it != all_buddies.end(); ++buddy_it)
- avatar_ids.push_back(buddy_it->first);
+ mFriendVec.push_back(buddy_it->first);
- // do refresh the friend list
- if (avatar_ids.size() > 0)
- have_names = mFriendList->updateList(avatar_ids);
- else
- mFriendList->setCommentText(getString("no_friends"));
+ return filterFriendList();
}
- return have_names;
+ return true;
}
-bool LLPanelPeople::updateFriendList(U32 changed_mask)
+bool LLPanelPeople::updateNearbyList()
{
- // Refresh names.
- if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
- {
- return refreshFriendNames(changed_mask);
- }
-
+ LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+ filterNearbyList();
+
return true;
}
-bool LLPanelPeople::updateNearbyList()
+bool LLPanelPeople::updateRecentList()
{
- std::vector<LLUUID> avatar_ids;
+ LLRecentPeople::instance().get(mRecentVec);
+ filterRecentList();
- LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+ return true;
+}
- mNearbyList->updateList(avatar_ids);
+bool LLPanelPeople::updateGroupList()
+{
+ bool have_names = mGroupList->update(mFilterSubString);
- if (avatar_ids.size() == 0)
- mNearbyList->setCommentText(getString("no_one_near"));
+ if (mGroupList->isEmpty())
+ mGroupList->setCommentText(getString("no_groups"));
- return true;
+ return have_names;
}
-bool LLPanelPeople::updateRecentList()
+bool LLPanelPeople::filterFriendList()
{
- std::vector<LLUUID> avatar_ids;
+ // We must always update Friends list to clear the latest removed friend.
+ bool have_names = mFriendList->update(mFriendVec, mFilterSubString);
- LLRecentPeople::instance().get(avatar_ids);
-
- if (avatar_ids.size() > 0)
- return mRecentList->updateList(avatar_ids);
+ if (mFriendVec.size() == 0)
+ mFriendList->setCommentText(getString("no_friends"));
- mRecentList->setCommentText(getString("no_people"));
- return true;
+ return have_names;
}
-bool LLPanelPeople::updateGroupList()
+bool LLPanelPeople::filterNearbyList()
+{
+ bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
+
+ if (mNearbyVec.size() == 0)
+ mNearbyList->setCommentText(getString("no_one_near"));
+
+ return have_names;
+}
+
+bool LLPanelPeople::filterRecentList()
{
- return mGroupList->updateList();
+ if (mRecentVec.size() > 0)
+ return mRecentList->update(mRecentVec, mFilterSubString);
+
+ mRecentList->setCommentText(getString("no_people"));
+
+ return true;
}
void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
@@ -433,10 +494,10 @@ void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_si
void LLPanelPeople::updateButtons()
{
std::string cur_tab = mTabContainer->getCurrentPanel()->getName();
- bool nearby_tab_active = (cur_tab == "nearby_panel");
- bool friends_tab_active = (cur_tab == "friends_panel");
- bool group_tab_active = (cur_tab == "groups_panel");
- bool recent_tab_active = (cur_tab == "recent_panel");
+ bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME);
+ bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME);
+ bool group_tab_active = (cur_tab == GROUP_TAB_NAME);
+ bool recent_tab_active = (cur_tab == RECENT_TAB_NAME);
LLUUID selected_id;
buttonSetVisible("group_info_btn", group_tab_active);
@@ -449,17 +510,19 @@ void LLPanelPeople::updateButtons()
if (group_tab_active)
{
+ bool item_selected = mGroupList->getFirstSelected() != NULL;
bool cur_group_active = true;
- selected_id = mGroupList->getCurrentID();
- if (selected_id.notNull())
+ if (item_selected)
+ {
+ selected_id = mGroupList->getCurrentID();
cur_group_active = (gAgent.getGroupID() == selected_id);
-
- bool item_selected = selected_id.notNull();
+ }
+
LLPanel* groups_panel = mTabContainer->getCurrentPanel();
- groups_panel->childSetEnabled("activate_btn", !item_selected || !cur_group_active); // "none" or a non-active group selected
+ groups_panel->childSetEnabled("activate_btn", item_selected && !cur_group_active); // "none" or a non-active group selected
groups_panel->childSetEnabled("plus_btn", item_selected);
- groups_panel->childSetEnabled("minus_btn", item_selected);
+ groups_panel->childSetEnabled("minus_btn", item_selected && selected_id.notNull());
}
else
{
@@ -489,11 +552,11 @@ LLAvatarList* LLPanelPeople::getActiveAvatarList() const
{
std::string cur_tab = mTabContainer->getCurrentPanel()->getName();
- if (cur_tab == "friends_panel")
+ if (cur_tab == FRIENDS_TAB_NAME)
return mFriendList;
- if (cur_tab == "nearby_panel")
+ if (cur_tab == NEARBY_TAB_NAME)
return mNearbyList;
- if (cur_tab == "recent_panel")
+ if (cur_tab == RECENT_TAB_NAME)
return mRecentList;
return NULL;
@@ -535,15 +598,20 @@ void LLPanelPeople::onVisibilityChange(BOOL new_visibility)
}
else
{
- // Make the tab-container re-select current tab
- // for onTabSelected() callback to get called.
- // (currently this is needed to reactivate nearby list updates
- // when we get visible)
- mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
+ reSelectedCurrentTab();
}
}
-void LLPanelPeople::onSearchEdit(const std::string& search_string)
+// Make the tab-container re-select current tab
+// for onTabSelected() callback to get called.
+// (currently this is needed to reactivate nearby list updates
+// when we get visible)
+void LLPanelPeople::reSelectedCurrentTab()
+{
+ mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
+}
+
+void LLPanelPeople::onFilterEdit(const std::string& search_string)
{
if (mFilterSubString == search_string)
return;
@@ -552,13 +620,21 @@ void LLPanelPeople::onSearchEdit(const std::string& search_string)
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
- mSearchEditor->setText(mFilterSubString);
+ mFilterEditor->setText(mFilterSubString);
+
+ // Apply new filter to all tabs.
+ filterNearbyList();
+ filterFriendList();
+ filterRecentList();
+ updateGroupList();
+
+ updateButtons();
}
void LLPanelPeople::onTabSelected(const LLSD& param)
{
std::string tab_name = getChild<LLPanel>(param.asString())->getName();
- mNearbyListUpdater->setActive(tab_name == "nearby_panel");
+ mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);
updateButtons();
}
@@ -583,7 +659,7 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
void LLPanelPeople::onViewProfileButtonClicked()
{
LLUUID id = getCurrentItemID();
- LLFriendActions::showProfile(id);
+ LLAvatarActions::showProfile(id);
}
void LLPanelPeople::onAddFriendButtonClicked()
@@ -593,7 +669,7 @@ void LLPanelPeople::onAddFriendButtonClicked()
{
std::string name;
gCacheName->getFullName(id, name);
- LLFriendActions::requestFriendshipDialog(id, name);
+ LLAvatarActions::requestFriendshipDialog(id, name);
}
}
@@ -610,7 +686,7 @@ void LLPanelPeople::onAddFriendWizButtonClicked()
void LLPanelPeople::onDeleteFriendButtonClicked()
{
- LLFriendActions::removeFriendDialog(getCurrentItemID());
+ LLAvatarActions::removeFriendDialog(getCurrentItemID());
}
void LLPanelPeople::onGroupInfoButtonClicked()
@@ -632,7 +708,7 @@ void LLPanelPeople::onImButtonClicked()
LLUUID id = getCurrentItemID();
if (id.notNull())
{
- LLFriendActions::startIM(id);
+ LLAvatarActions::startIM(id);
}
}
@@ -648,7 +724,7 @@ void LLPanelPeople::onAvatarPicked(
void*)
{
if (!names.empty() && !ids.empty())
- LLFriendActions::requestFriendshipDialog(ids[0], names[0]);
+ LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
}
bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
@@ -673,11 +749,9 @@ void LLPanelPeople::onGroupPlusButtonClicked()
void LLPanelPeople::onGroupMinusButtonClicked()
{
- LLMenuGL* minus_menu = (LLMenuGL*)mGroupMinusMenuHandle.get();
- if (!minus_menu)
- return;
-
- showGroupMenu(minus_menu);
+ LLUUID group_id = getCurrentItemID();
+ if (group_id.notNull())
+ LLGroupActions::leave(group_id);
}
void LLPanelPeople::onGroupPlusMenuItemClicked(const LLSD& userdata)
@@ -690,19 +764,6 @@ void LLPanelPeople::onGroupPlusMenuItemClicked(const LLSD& userdata)
LLGroupActions::create();
}
-void LLPanelPeople::onGroupMinusMenuItemClicked(const LLSD& userdata)
-{
- std::string chosen_item = userdata.asString();
-
- LLUUID group_id = getCurrentItemID();
- if (chosen_item == "leave_group")
- LLGroupActions::leave(group_id);
- /*
- else if (chosen_item == "delete_group")
- ; // *TODO: how to delete a group?
- */
-}
-
void LLPanelPeople::onCallButtonClicked()
{
// *TODO: not implemented yet
@@ -710,7 +771,7 @@ void LLPanelPeople::onCallButtonClicked()
void LLPanelPeople::onTeleportButtonClicked()
{
- LLFriendActions::offerTeleport(getCurrentItemID());
+ LLAvatarActions::offerTeleport(getCurrentItemID());
}
void LLPanelPeople::onShareButtonClicked()
@@ -725,5 +786,22 @@ void LLPanelPeople::onMoreButtonClicked()
void LLPanelPeople::onOpen(const LLSD& key)
{
- mTabContainer->selectTab(key.asInteger());
+ // Profile View is activated through LLSideTray::showPanel(),
+ // hide Profile View to be able to see Panel People content
+ hideProfileView();
+
+ std::string tab_name = key.asString();
+ if (!tab_name.empty())
+ mTabContainer->selectTabByName(tab_name);
+ else
+ reSelectedCurrentTab();
+}
+
+void LLPanelPeople::hideProfileView()
+{
+ LLView* view = getChildView("panel_profile_view",true,false);
+ if(view && view->getVisible())
+ {
+ view->setVisible(false);
+ }
}