summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp4
-rw-r--r--indra/newview/llparticipantlist.cpp75
-rw-r--r--indra/newview/llparticipantlist.h21
-rw-r--r--indra/newview/skins/default/xui/en/menu_participant_list.xml24
4 files changed, 121 insertions, 3 deletions
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index ae1c28c7ab..8d03f9e686 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -247,6 +247,10 @@ void LLPanelGroupControlPanel::draw()
//Remove event does not raised until speakerp->mActivityTimer.hasExpired() is false, see LLSpeakerManager::update()
//so we need update it to raise needed event
mSpeakerManager->update(true);
+ // Need to refresh participants to display ones not in voice as disabled and
+ // resort the avatar list if it's in sort by recent speaker order.
+ if (mParticipantList)
+ mParticipantList->refreshVoiceState();
LLPanelChatControlPanel::draw();
}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index e8aa1e9831..8fb4063ea7 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -39,7 +39,6 @@
#include "llimview.h"
#include "llparticipantlist.h"
-#include "llavatarlist.h"
#include "llspeakers.h"
#include "llviewermenu.h"
#include "llvoiceclient.h"
@@ -204,6 +203,11 @@ void LLParticipantList::setSortOrder(EParticipantSortOrder order)
}
}
+LLParticipantList::EParticipantSortOrder LLParticipantList::getSortOrder()
+{
+ return mSortOrder;
+}
+
void LLParticipantList::refreshVoiceState()
{
LLSpeakerMgr::speaker_list_t speakers;
@@ -223,6 +227,12 @@ void LLParticipantList::refreshVoiceState()
item->setOnline(!is_in_voice);
}
}
+ if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder())
+ {
+ // Resort avatar list
+ mAvatarList->setDirty(true);
+ sort();
+ }
}
bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -312,7 +322,6 @@ void LLParticipantList::sort()
if ( !mAvatarList )
return;
- // TODO: Implement more sorting orders after specs updating (EM)
switch ( mSortOrder ) {
case E_SORT_BY_NAME :
// if mExcludeAgent == true , then no need to keep agent on top of the list
@@ -326,6 +335,12 @@ void LLParticipantList::sort()
mAvatarList->sort();
}
break;
+ case E_SORT_BY_RECENT_SPEAKERS:
+ if (mSortByRecentSpeakers.isNull())
+ mSortByRecentSpeakers = new LLAvatarItemRecentSpeakerComparator(*this);
+ mAvatarList->setComparator(mSortByRecentSpeakers.get());
+ mAvatarList->sort();
+ break;
default :
llwarns << "Unrecognized sort order for " << mAvatarList->getName() << llendl;
return;
@@ -402,6 +417,7 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ registrar.add("ParticipantList.Sort", boost::bind(&LLParticipantList::LLParticipantListMenu::sortParticipantList, this, _2));
registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleAllowTextChat, this, _2));
registrar.add("ParticipantList.ToggleMuteText", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteText, this, _2));
@@ -447,6 +463,24 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteSelected", false);
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteOthers", false);
}
+
+ // Don't show sort options for P2P chat
+ bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
+ LLMenuGL::sMenuContainer->childSetVisible("SortByName", is_sort_visible);
+ LLMenuGL::sMenuContainer->childSetVisible("SortByRecentSpeakers", is_sort_visible);
+}
+
+void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata)
+{
+ std::string param = userdata.asString();
+ if ("sort_by_name" == param)
+ {
+ mParent.setSortOrder(E_SORT_BY_NAME);
+ }
+ else if ("sort_by_recent_speakers" == param)
+ {
+ mParent.setSortOrder(E_SORT_BY_RECENT_SPEAKERS);
+ }
}
void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata)
@@ -616,8 +650,45 @@ bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD&
{
return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
}
+ else if(item == "is_sorted_by_name")
+ {
+ return E_SORT_BY_NAME == mParent.mSortOrder;
+ }
+ else if(item == "is_sorted_by_recent_speakers")
+ {
+ return E_SORT_BY_RECENT_SPEAKERS == mParent.mSortOrder;
+ }
return false;
}
+bool LLParticipantList::LLAvatarItemRecentSpeakerComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const
+{
+ if (mParent.mSpeakerMgr)
+ {
+ LLPointer<LLSpeaker> lhs = mParent.mSpeakerMgr->findSpeaker(avatar_item1->getAvatarId());
+ LLPointer<LLSpeaker> rhs = mParent.mSpeakerMgr->findSpeaker(avatar_item2->getAvatarId());
+ if ( lhs.notNull() && rhs.notNull() )
+ {
+ // Compare by last speaking time
+ if( lhs->mLastSpokeTime != rhs->mLastSpokeTime )
+ return ( lhs->mLastSpokeTime > rhs->mLastSpokeTime );
+ else if ( lhs->mSortIndex != rhs->mSortIndex )
+ return ( lhs->mSortIndex < rhs->mSortIndex );
+ }
+ else if ( lhs.notNull() )
+ {
+ // True if only avatar_item1 speaker info available
+ return true;
+ }
+ else if ( rhs.notNull() )
+ {
+ // False if only avatar_item2 speaker info available
+ return false;
+ }
+ }
+ // By default compare by name.
+ return LLAvatarItemNameComparator::doCompare(avatar_item1, avatar_item2);
+}
+
//EOF
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index b85d4c9bc4..21eda86edd 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -34,6 +34,7 @@
#include "llevent.h"
#include "llpanelpeoplemenus.h"
#include "llimview.h"
+#include "llavatarlist.h" // for LLAvatarItemRecentSpeakerComparator
class LLSpeakerMgr;
class LLAvatarList;
@@ -49,12 +50,14 @@ class LLParticipantList
typedef enum e_participant_sort_oder {
E_SORT_BY_NAME = 0,
+ E_SORT_BY_RECENT_SPEAKERS = 1,
} EParticipantSortOrder;
/**
* Set and sort Avatarlist by given order
*/
void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME);
+ EParticipantSortOrder getSortOrder();
/**
* Refreshes participants to display ones not in voice as disabled.
@@ -139,6 +142,7 @@ class LLParticipantList
bool enableContextMenuItem(const LLSD& userdata);
bool checkContextMenuItem(const LLSD& userdata);
+ void sortParticipantList(const LLSD& userdata);
void toggleAllowTextChat(const LLSD& userdata);
void toggleMute(const LLSD& userdata, U32 flags);
void toggleMuteText(const LLSD& userdata);
@@ -195,6 +199,21 @@ class LLParticipantList
void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute);
};
+ /**
+ * Comparator for comparing avatar items by last spoken time
+ */
+ class LLAvatarItemRecentSpeakerComparator : public LLAvatarItemNameComparator, public LLRefCount
+ {
+ LOG_CLASS(LLAvatarItemRecentSpeakerComparator);
+ public:
+ LLAvatarItemRecentSpeakerComparator(LLParticipantList& parent):mParent(parent){};
+ virtual ~LLAvatarItemRecentSpeakerComparator() {};
+ protected:
+ virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
+ private:
+ LLParticipantList& mParent;
+ };
+
private:
void onAvatarListDoubleClicked(LLAvatarList* list);
void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
@@ -240,4 +259,6 @@ class LLParticipantList
boost::signals2::connection mAvatarListDoubleClickConnection;
boost::signals2::connection mAvatarListRefreshConnection;
boost::signals2::connection mAvatarListReturnConnection;
+
+ LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
};
diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml
index faf33bd1b1..31263fbea8 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml
@@ -2,7 +2,29 @@
<context_menu
layout="topleft"
name="Participant List Context Menu">
- <menu_item_call
+ <menu_item_check
+ label="Sort by Name"
+ layout="topleft"
+ name="SortByName">
+ <menu_item_check.on_click
+ function="ParticipantList.Sort"
+ parameter="sort_by_name" />
+ <menu_item_check.on_check
+ function="ParticipantList.CheckItem"
+ parameter="is_sorted_by_name" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Recent Speakers"
+ layout="topleft"
+ name="SortByRecentSpeakers">
+ <menu_item_check.on_click
+ function="ParticipantList.Sort"
+ parameter="sort_by_recent_speakers" />
+ <menu_item_check.on_check
+ function="ParticipantList.CheckItem"
+ parameter="is_sorted_by_recent_speakers" />
+ </menu_item_check>
+ <menu_item_call
label="View Profile"
layout="topleft"
name="View Profile">