From 73769180f363556d5517e3070fc4a2ac61e713d6 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 31 Aug 2012 19:22:41 +0300
Subject: CHUI-298 FIXED (Conversation started as an IM and then goes to voice
 call does not show as call in conversation log)

- Show voice icon when call is started
- Added flag LLConversation::mIsConversationPast which means that this conversation is finished and any of its data can't be changed. I.e. it cannot be reused.
- When session removed (i.e. finished) corresponding conversation is marked as Past conversation. I.e. mIsConversationPast is true.
- Added changed(const LLUUID& session_id, U32 mask) method to LLConversationLog to notify particular conversation. This is used in LLConversationLogList to update its particular item and not to rebuild the whole list.
---
 indra/newview/llconversationlog.cpp       | 54 ++++++++++++++++++++++++++++++-
 indra/newview/llconversationlog.h         | 25 ++++++++++----
 indra/newview/llconversationloglist.cpp   | 22 +++++++++++++
 indra/newview/llconversationloglist.h     |  1 +
 indra/newview/llconversationloglistitem.h |  4 +--
 indra/newview/llvoicechannel.cpp          |  2 +-
 indra/newview/llvoicechannel.h            |  2 +-
 7 files changed, 99 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 486cea4064..23ccc78a0f 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -33,7 +33,8 @@ struct Conversation_params
 {
 	Conversation_params(time_t time)
 	:	mTime(time),
-		mTimestamp(LLConversation::createTimestamp(time))
+		mTimestamp(LLConversation::createTimestamp(time)),
+		mIsConversationPast(true)
 	{}
 
 	time_t		mTime;
@@ -44,6 +45,7 @@ struct Conversation_params
 	LLUUID		mSessionID;
 	LLUUID		mParticipantID;
 	bool		mIsVoice;
+	bool		mIsConversationPast;
 	bool		mHasOfflineIMs;
 };
 
@@ -60,6 +62,7 @@ LLConversation::LLConversation(const Conversation_params& params)
 	mSessionID(params.mSessionID),
 	mParticipantID(params.mParticipantID),
 	mIsVoice(params.mIsVoice),
+	mIsConversationPast(params.mIsConversationPast),
 	mHasOfflineIMs(params.mHasOfflineIMs)
 {
 	setListenIMFloaterOpened();
@@ -74,6 +77,7 @@ LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
 	mSessionID(session.mSessionID),
 	mParticipantID(session.mOtherParticipantID),
 	mIsVoice(session.mStartedAsIMCall),
+	mIsConversationPast(false),
 	mHasOfflineIMs(session.mHasOfflineMessage)
 {
 	setListenIMFloaterOpened();
@@ -89,6 +93,7 @@ LLConversation::LLConversation(const LLConversation& conversation)
 	mSessionID			= conversation.getSessionID();
 	mParticipantID		= conversation.getParticipantID();
 	mIsVoice			= conversation.isVoice();
+	mIsConversationPast = conversation.isConversationPast();
 	mHasOfflineIMs		= conversation.hasOfflineMessages();
 
 	setListenIMFloaterOpened();
@@ -99,6 +104,14 @@ LLConversation::~LLConversation()
 	mIMFloaterShowedConnection.disconnect();
 }
 
+void LLConversation::setIsVoice(bool is_voice)
+{
+	if (mIsConversationPast)
+		return;
+
+	mIsVoice = is_voice;
+}
+
 void LLConversation::onIMFloaterShown(const LLUUID& session_id)
 {
 	if (mSessionID == session_id)
@@ -228,6 +241,21 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
 	{
 		LLConversation conversation(*session);
 		LLConversationLog::instance().logConversation(conversation);
+		session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2));
+	}
+}
+
+void LLConversationLog::sessionRemoved(const LLUUID& session_id)
+{
+	conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin();
+
+	for (; rev_iter != mConversations.rend(); ++rev_iter)
+	{
+		if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast())
+		{
+			rev_iter->setIsPast(true);
+			return; // return here because only one session with session_id may be active
+		}
 	}
 }
 
@@ -350,3 +378,27 @@ void LLConversationLog::notifyObservers()
 		(*iter)->changed();
 	}
 }
+
+void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask)
+{
+	std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
+	for (; iter != mObservers.end(); ++iter)
+	{
+		(*iter)->changed(session_id, mask);
+	}
+}
+
+void LLConversationLog::onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state)
+{
+	conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin();
+
+	for (; rev_iter != mConversations.rend(); ++rev_iter)
+	{
+		if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast() && LLVoiceChannel::STATE_CALL_STARTED == state)
+		{
+			rev_iter->setIsVoice(true);
+			notifyPrticularConversationObservers(session_id, LLConversationLogObserver::VOICE_STATE);
+			return; // return here because only one session with session_id may be active
+		}
+	}
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index a7457d55e3..f2b6a67c92 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -57,8 +57,12 @@ public:
 	const std::string&	getTimestamp()			const	{ return mTimestamp; }
 	const time_t&		getTime()				const	{ return mTime; }
 	bool				isVoice()				const	{ return mIsVoice; }
+	bool				isConversationPast()	const	{ return mIsConversationPast; }
 	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
 
+	void	setIsVoice(bool is_voice);
+	void	setIsPast (bool is_past) { mIsConversationPast = is_past; }
+
 	/*
 	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
 	 */
@@ -87,6 +91,7 @@ private:
 	LLUUID			mParticipantID;
 	bool			mIsVoice;
 	bool			mHasOfflineIMs;
+	bool			mIsConversationPast; // once session is finished conversation became past forever
 	std::string		mTimestamp; // conversation start time in form of: mm/dd/yyyy hh:mm
 };
 
@@ -122,12 +127,14 @@ public:
 
 	// LLIMSessionObserver triggers
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){}							// Stub
-	virtual void sessionRemoved(const LLUUID& session_id){}										// Stub
-	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){}	// Stub
+	virtual void sessionRemoved(const LLUUID& session_id);
+	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){};								// Stub
+	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){};	// Stub
 
-	// Triggered by LLFriendObserver change
 	void notifyObservers();
+	void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask);
+
+	void onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state);
 
 	/**
 	 * public method which is called on viewer exit to save conversation log
@@ -140,8 +147,7 @@ private:
 
 	/**
 	 * constructs file name in which conversations log will be saved
-	 * file name template: agentID.call_log.
-	 * For example: a086icaa-782d-88d0-ae29-987a55c99sss.call_log
+	 * file name is conversation.log
 	 */
 	std::string getFileName();
 
@@ -158,8 +164,15 @@ private:
 class LLConversationLogObserver
 {
 public:
+
+	enum EConversationChange
+		{
+			VOICE_STATE = 1
+		};
+
 	virtual ~LLConversationLogObserver(){}
 	virtual void changed() = 0;
+	virtual void changed(const LLUUID& session_id, U32 mask){};
 };
 
 #endif /* LLCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 94be9055bd..d39e090c22 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -141,6 +141,28 @@ void LLConversationLogList::changed()
 	refresh();
 }
 
+void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
+{
+	if (mask & LLConversationLogObserver::VOICE_STATE)
+	{
+		std::vector<LLPanel*> panels;
+		LLFlatListViewEx::getItems(panels);
+
+		std::vector<LLPanel*>::iterator iter = panels.begin();
+
+		for (; iter != panels.end(); ++iter)
+		{
+			LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter);
+
+			if (item && session_id == item->getConversation()->getSessionID() && !item->getConversation()->isConversationPast())
+			{
+				item->initIcons();
+				return;
+			}
+		}
+	}
+}
+
 void LLConversationLogList::addNewItem(const LLConversation* conversation)
 {
 	LLConversationLogListItem* item = new LLConversationLogListItem(&*conversation);
diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h
index dff34a74c6..5e7fc0a9fb 100644
--- a/indra/newview/llconversationloglist.h
+++ b/indra/newview/llconversationloglist.h
@@ -68,6 +68,7 @@ public:
 	 * Changes from LLConversationLogObserver
 	 */
 	virtual void changed();
+	virtual void changed(const LLUUID& session_id, U32 mask);
 
 private:
 
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
index 8943e11604..2aaafa0fba 100644
--- a/indra/newview/llconversationloglistitem.h
+++ b/indra/newview/llconversationloglistitem.h
@@ -64,10 +64,10 @@ public:
 
 	void onDoubleClick();
 
-private:
-
 	void initIcons();
 
+private:
+
 	const LLConversation* mConversation;
 
 	LLTextBox*		mConversationName;
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index bd12328a6b..ceff75a0cc 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -414,7 +414,7 @@ void LLVoiceChannel::doSetState(const EState& new_state)
 	mState = new_state;
 
 	if (!mStateChangedCallback.empty())
-		mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent);
+		mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent, mSessionID);
 }
 
 //static
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index b8597ee5cb..fed44974fd 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -52,7 +52,7 @@ public:
 		OUTGOING_CALL
 	} EDirection;
 
-	typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent)> state_changed_signal_t;
+	typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent, const LLUUID& session_id)> state_changed_signal_t;
 
 	// on current channel changed signal
 	typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t;
-- 
cgit v1.2.3