From ad070b9155e2fddfc746319003253248ceb0eba3 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 28 Aug 2012 23:13:10 -0700
Subject: CHUI-280 : Implement all LLConversationModel updates in
 LLParticipantList. Allow mAvatarList to be NULL.

---
 indra/newview/llconversationmodel.cpp |  31 +++++-
 indra/newview/llconversationmodel.h   |   6 +-
 indra/newview/llparticipantlist.cpp   | 193 +++++++++++++++++++---------------
 3 files changed, 137 insertions(+), 93 deletions(-)

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 9b353809db..dbf5ac6e03 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -98,15 +98,24 @@ LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolde
 {
 }
 
-void LLConversationItemSession::addParticipant(LLConversationItemParticipant* item)
+void LLConversationItemSession::addParticipant(LLConversationItemParticipant* participant)
 {
-	addChild(item);
+	addChild(participant);
 	mIsLoaded = true;
 }
 
-void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* item)
+void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
 {
-	removeChild(item);
+	removeChild(participant);
+}
+
+void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		removeParticipant(participant);
+	}
 }
 
 void LLConversationItemSession::clearParticipants()
@@ -135,7 +144,19 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const
 void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_id, bool is_muted)
 {
 	LLConversationItemParticipant* participant = findParticipant(participant_id);
-	participant->setIsMuted(is_muted);
+	if (participant)
+	{
+		participant->setIsMuted(is_muted);
+	}
+}
+
+void LLConversationItemSession::setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		participant->setIsModerator(is_moderator);
+	}
 }
 
 //
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 484c0feb36..aa79e5aeb0 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -116,12 +116,14 @@ public:
 	virtual ~LLConversationItemSession() {}
 	
 	void setSessionID(const LLUUID& session_id) { mUUID = session_id; }
-	void addParticipant(LLConversationItemParticipant* item);
-	void removeParticipant(LLConversationItemParticipant* item);
+	void addParticipant(LLConversationItemParticipant* participant);
+	void removeParticipant(LLConversationItemParticipant* participant);
+	void removeParticipant(const LLUUID& participant_id);
 	void clearParticipants();
 	LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
 
 	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
+	void setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator);
 	
 	bool isLoaded() { return mIsLoaded; }
 	
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 6511b0a1a6..35c1a34a26 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -52,11 +52,14 @@ static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR;
 // helper function to update AvatarList Item's indicator in the voice participant list
 static void update_speaker_indicator(const LLAvatarList* const avatar_list, const LLUUID& avatar_uuid, bool is_muted)
 {
-	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(avatar_list->getItemByValue(avatar_uuid));
-	if (item)
+	if (avatar_list)
 	{
-		LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator");
-		indicator->setIsMuted(is_muted);
+		LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(avatar_list->getItemByValue(avatar_uuid));
+		if (item)
+		{
+			LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator");
+			indicator->setIsMuted(is_muted);
+		}
 	}
 }
 
@@ -281,10 +284,13 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 
 LLParticipantList::~LLParticipantList()
 {
-	mAvatarListDoubleClickConnection.disconnect();
-	mAvatarListRefreshConnection.disconnect();
-	mAvatarListReturnConnection.disconnect();
-	mAvatarListToggleIconsConnection.disconnect();
+	if (mAvatarList)
+	{
+		mAvatarListDoubleClickConnection.disconnect();
+		mAvatarListRefreshConnection.disconnect();
+		mAvatarListReturnConnection.disconnect();
+		mAvatarListToggleIconsConnection.disconnect();
+	}
 
 	// It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged()
 	// See ticket EXT-3427
@@ -300,16 +306,22 @@ LLParticipantList::~LLParticipantList()
 		mParticipantListMenu = NULL;
 	}
 
-	mAvatarList->setContextMenu(NULL);
-	mAvatarList->setComparator(NULL);
+	if (mAvatarList)
+	{
+		mAvatarList->setContextMenu(NULL);
+		mAvatarList->setComparator(NULL);
+	}
 
 	delete mAvalineUpdater;
 }
 
 void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
 {
-	mAvatarList->setSpeakingIndicatorsVisible(visible);
-};
+	if (mAvatarList)
+	{
+		mAvatarList->setSpeakingIndicatorsVisible(visible);
+	}
+}
 
 void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
 {
@@ -330,82 +342,81 @@ void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
 void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 {
 	LLAvatarList* list = dynamic_cast<LLAvatarList*>(ctrl);
-	if (list)
+	const std::string moderator_indicator(LLTrans::getString("IM_moderator_label")); 
+	const std::size_t moderator_indicator_len = moderator_indicator.length();
+
+	// Firstly remove moderators indicator
+	std::set<LLUUID>::const_iterator
+		moderator_list_it = mModeratorToRemoveList.begin(),
+		moderator_list_end = mModeratorToRemoveList.end();
+	for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
 	{
-		const std::string moderator_indicator(LLTrans::getString("IM_moderator_label")); 
-		const std::size_t moderator_indicator_len = moderator_indicator.length();
-
-		// Firstly remove moderators indicator
-		std::set<LLUUID>::const_iterator
-			moderator_list_it = mModeratorToRemoveList.begin(),
-			moderator_list_end = mModeratorToRemoveList.end();
-		for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
+		LLAvatarListItem* item = (list ? dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it)) : NULL);
+		if ( item )
 		{
-			LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
-			if ( item )
+			std::string name = item->getAvatarName();
+			std::string tooltip = item->getAvatarToolTip();
+			size_t found = name.find(moderator_indicator);
+			if (found != std::string::npos)
 			{
-				std::string name = item->getAvatarName();
-				std::string tooltip = item->getAvatarToolTip();
-				size_t found = name.find(moderator_indicator);
-				if (found != std::string::npos)
-				{
-					name.erase(found, moderator_indicator_len);
-					item->setAvatarName(name);
-				}
-				found = tooltip.find(moderator_indicator);
-				if (found != tooltip.npos)
-				{
-					tooltip.erase(found, moderator_indicator_len);
-					item->setAvatarToolTip(tooltip);
-				}
+				name.erase(found, moderator_indicator_len);
+				item->setAvatarName(name);
+			}
+			found = tooltip.find(moderator_indicator);
+			if (found != tooltip.npos)
+			{
+				tooltip.erase(found, moderator_indicator_len);
+				item->setAvatarToolTip(tooltip);
 			}
 		}
+		setParticipantIsModerator(*moderator_list_it,false);
+	}
 
-		mModeratorToRemoveList.clear();
+	mModeratorToRemoveList.clear();
 
-		// Add moderators indicator
-		moderator_list_it = mModeratorList.begin();
-		moderator_list_end = mModeratorList.end();
-		for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
+	// Add moderators indicator
+	moderator_list_it = mModeratorList.begin();
+	moderator_list_end = mModeratorList.end();
+	for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
+	{
+		LLAvatarListItem* item = (list ? dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it)) : NULL);
+		if ( item )
 		{
-			LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
-			if ( item )
+			std::string name = item->getAvatarName();
+			std::string tooltip = item->getAvatarToolTip();
+			size_t found = name.find(moderator_indicator);
+			if (found == std::string::npos)
 			{
-				std::string name = item->getAvatarName();
-				std::string tooltip = item->getAvatarToolTip();
-				size_t found = name.find(moderator_indicator);
-				if (found == std::string::npos)
-				{
-					name += " ";
-					name += moderator_indicator;
-					item->setAvatarName(name);
-				}
-				found = tooltip.find(moderator_indicator);
-				if (found == std::string::npos)
-				{
-					tooltip += " ";
-					tooltip += moderator_indicator;
-					item->setAvatarToolTip(tooltip);
-				}
+				name += " ";
+				name += moderator_indicator;
+				item->setAvatarName(name);
+			}
+			found = tooltip.find(moderator_indicator);
+			if (found == std::string::npos)
+			{
+				tooltip += " ";
+				tooltip += moderator_indicator;
+				item->setAvatarToolTip(tooltip);
 			}
 		}
+		setParticipantIsModerator(*moderator_list_it,true);
+	}
 
-		// update voice mute state of all items. See EXT-7235
-		LLSpeakerMgr::speaker_list_t speaker_list;
+	// update voice mute state of all items. See EXT-7235
+	LLSpeakerMgr::speaker_list_t speaker_list;
 
-		// Use also participants which are not in voice session now (the second arg is TRUE).
-		// They can already have mModeratorMutedVoice set from the previous voice session
-		// and LLSpeakerVoiceModerationEvent will not be sent when speaker manager is updated next time.
-		mSpeakerMgr->getSpeakerList(&speaker_list, TRUE);
-		for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++)
-		{
-			const LLPointer<LLSpeaker>& speakerp = *it;
+	// Use also participants which are not in voice session now (the second arg is TRUE).
+	// They can already have mModeratorMutedVoice set from the previous voice session
+	// and LLSpeakerVoiceModerationEvent will not be sent when speaker manager is updated next time.
+	mSpeakerMgr->getSpeakerList(&speaker_list, TRUE);
+	for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++)
+	{
+		const LLPointer<LLSpeaker>& speakerp = *it;
 
-			if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
-			{
-				setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
-				update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice);
-			}
+		if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
+		{
+			setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
+			update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice);
 		}
 	}
 }
@@ -506,7 +517,7 @@ bool LLParticipantList::isHovered()
 {
 	S32 x, y;
 	LLUI::getMousePositionScreen(&x, &y);
-	return mAvatarList->calcScreenRect().pointInRect(x, y);
+	return (mAvatarList ? mAvatarList->calcScreenRect().pointInRect(x, y) : false);
 }
 
 bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -525,21 +536,30 @@ bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, co
 
 bool LLParticipantList::onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
-	uuid_vec_t& group_members = mAvatarList->getIDs();
-	uuid_vec_t::iterator pos = std::find(group_members.begin(), group_members.end(), event->getValue().asUUID());
-	if(pos != group_members.end())
+	LLUUID avatar_id = event->getValue().asUUID();
+	if (mAvatarList)
 	{
-		group_members.erase(pos);
-		mAvatarList->setDirty();
+		uuid_vec_t& group_members = mAvatarList->getIDs();
+		uuid_vec_t::iterator pos = std::find(group_members.begin(), group_members.end(), avatar_id);
+		if(pos != group_members.end())
+		{
+			group_members.erase(pos);
+			mAvatarList->setDirty();
+		}
 	}
+	removeParticipant(avatar_id);
 	return true;
 }
 
 bool LLParticipantList::onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
-	uuid_vec_t& group_members = mAvatarList->getIDs();
-	group_members.clear();
-	mAvatarList->setDirty();
+	if (mAvatarList)
+	{
+		uuid_vec_t& group_members = mAvatarList->getIDs();
+		group_members.clear();
+		mAvatarList->setDirty();
+	}
+	clearParticipants();
 	return true;
 }
 
@@ -587,6 +607,7 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
 
 void LLParticipantList::sort()
 {
+	// *TODO : Merov : Need to plan for sort() for LLConversationModel
 	if ( !mAvatarList )
 		return;
 
@@ -631,7 +652,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		LLAvatarName avatar_name;
 		bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
 		participant = new LLConversationItemParticipant(!has_name ? "Avatar" : avatar_name.mDisplayName , avatar_id, mRootViewModel);
-		if ( mAvatarList)
+		if (mAvatarList)
 		{
 			mAvatarList->getIDs().push_back(avatar_id);
 			mAvatarList->setDirty();
@@ -642,7 +663,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
 		// Create a participant view model instance and add it to the linked list
 		participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
-		if ( mAvatarList)
+		if (mAvatarList)
 		{
 			mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
 		}
@@ -808,7 +829,7 @@ void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata,
 		LL_WARNS("Speakers") << "Speaker " << speaker_id << " not found" << llendl;
 		return;
 	}
-	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(mParent.mAvatarList->getItemByValue(speaker_id));
+	LLAvatarListItem* item = (mParent.mAvatarList ? dynamic_cast<LLAvatarListItem*>(mParent.mAvatarList->getItemByValue(speaker_id)) : NULL);
 	if (NULL == item) return;
 
 	name = item->getAvatarName();
-- 
cgit v1.2.3