From 1e2dcbfb3fbc8717ea594365ff165115b29df83a Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 11 Sep 2012 17:45:49 +0300
Subject: CHUI-326 FIXED (One entry per conversation with a user in
 conversation log timestamped with most recent utterance/activity.)

- Modified LLConversationLog to show only one entry per conversation with user. I.e. there can't be two conversations with the same session_id in LLConversationLog.
- Got rid of processing voice sessions
- Refactored creation of conversation in LLConversationLog
- Refactored a little bit LLConversation and LLConversationLog: function names and made some functions private
---
 indra/newview/llconversationlog.cpp         | 141 ++++++++++++++++------------
 indra/newview/llconversationlog.h           |  44 +++++----
 indra/newview/llconversationloglist.cpp     |  57 ++++++++---
 indra/newview/llconversationloglist.h       |   9 ++
 indra/newview/llconversationloglistitem.cpp |  10 ++
 indra/newview/llconversationloglistitem.h   |   8 +-
 indra/newview/llfloaterconversationlog.cpp  |  12 +--
 indra/newview/llfloaterconversationlog.h    |   5 -
 8 files changed, 187 insertions(+), 99 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index cc02e18698..239a89015f 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -37,7 +37,7 @@ struct Conversation_params
 	Conversation_params(time_t time)
 	:	mTime(time),
 		mTimestamp(LLConversation::createTimestamp(time)),
-		mIsConversationPast(true)
+		mIsVoice(false)
 	{}
 
 	time_t		mTime;
@@ -48,7 +48,6 @@ struct Conversation_params
 	LLUUID		mSessionID;
 	LLUUID		mParticipantID;
 	bool		mIsVoice;
-	bool		mIsConversationPast;
 	bool		mHasOfflineIMs;
 };
 
@@ -65,7 +64,6 @@ LLConversation::LLConversation(const Conversation_params& params)
 	mSessionID(params.mSessionID),
 	mParticipantID(params.mParticipantID),
 	mIsVoice(params.mIsVoice),
-	mIsConversationPast(params.mIsConversationPast),
 	mHasOfflineIMs(params.mHasOfflineIMs)
 {
 	setListenIMFloaterOpened();
@@ -80,7 +78,6 @@ LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
 	mSessionID(session.mSessionID),
 	mParticipantID(session.mOtherParticipantID),
 	mIsVoice(session.mStartedAsIMCall),
-	mIsConversationPast(false),
 	mHasOfflineIMs(session.mHasOfflineMessage)
 {
 	setListenIMFloaterOpened();
@@ -96,7 +93,6 @@ LLConversation::LLConversation(const LLConversation& conversation)
 	mSessionID			= conversation.getSessionID();
 	mParticipantID		= conversation.getParticipantID();
 	mIsVoice			= conversation.isVoice();
-	mIsConversationPast = conversation.isConversationPast();
 	mHasOfflineIMs		= conversation.hasOfflineMessages();
 
 	setListenIMFloaterOpened();
@@ -107,12 +103,10 @@ LLConversation::~LLConversation()
 	mIMFloaterShowedConnection.disconnect();
 }
 
-void LLConversation::setIsVoice(bool is_voice)
+void LLConversation::updateTimestamp()
 {
-	if (mIsConversationPast)
-		return;
-
-	mIsVoice = is_voice;
+	mTime = time_corrected();
+	mTimestamp = createTimestamp(mTime);
 }
 
 void LLConversation::onIMFloaterShown(const LLUUID& session_id)
@@ -154,14 +148,18 @@ void LLConversation::setListenIMFloaterOpened()
 	LLIMFloater* floater = LLIMFloater::findInstance(mSessionID);
 
 	bool has_offline_ims = !mIsVoice && mHasOfflineIMs;
-	bool ims_are_read = LLIMFloater::isVisible(floater) && floater->hasFocus();
+	bool offline_ims_visible = LLIMFloater::isVisible(floater) && floater->hasFocus();
 
 	// we don't need to listen for im floater with this conversation is opened
 	// if floater is already opened or this conversation doesn't have unread offline messages
-	if (has_offline_ims && !ims_are_read)
+	if (has_offline_ims && !offline_ims_visible)
 	{
 		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
 	}
+	else
+	{
+		mHasOfflineIMs = false;
+	}
 }
 
 /************************************************************************/
@@ -205,6 +203,7 @@ LLConversationLog::LLConversationLog()
 		if (ctrl->getValue().asBoolean())
 		{
 			LLIMMgr::instance().addSessionObserver(this);
+			newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
 		}
 	}
 
@@ -218,17 +217,80 @@ void LLConversationLog::observeIMSession()
 	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
 	{
 		LLIMMgr::instance().addSessionObserver(this);
+		LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
 	}
 	else
 	{
 		LLIMMgr::instance().removeSessionObserver(this);
+		newMessageSignalConnection.disconnect();
 	}
 }
 
-void LLConversationLog::logConversation(const LLConversation& conversation)
+void LLConversationLog::logConversation(const LLUUID& session_id)
 {
-	mConversations.push_back(conversation);
-	notifyObservers();
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+	LLConversation* conversation = findConversation(session_id);
+
+	if (session && conversation)
+	{
+		updateConversationTimestamp(conversation);
+	}
+	else if (session && !conversation)
+	{
+		createConversation(session_id);
+	}
+}
+
+void LLConversationLog::createConversation(const LLUUID& session_id)
+{
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+
+	if (session)
+	{
+		LLConversation conversation(*session);
+		mConversations.push_back(conversation);
+
+		if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType)
+		{
+			LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session));
+		}
+
+		notifyObservers();
+	}
+}
+
+void LLConversationLog::updateConversationName(const LLUUID& session_id, const std::string& name)
+{
+	LLConversation* conversation = findConversation(session_id);
+
+	if (conversation)
+	{
+		conversation->setConverstionName(name);
+		notifyPrticularConversationObservers(session_id, LLConversationLogObserver::CHANGED_NAME);
+	}
+}
+
+void LLConversationLog::updateConversationTimestamp(LLConversation* conversation)
+{
+	if (conversation)
+	{
+		conversation->updateTimestamp();
+		notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME);
+	}
+}
+
+LLConversation* LLConversationLog::findConversation(const LLUUID& session_id)
+{
+	conversations_vec_t::iterator conv_it = mConversations.begin();
+	for(; conv_it != mConversations.end(); ++conv_it)
+	{
+		if (conv_it->getSessionID() == session_id)
+		{
+			return &*conv_it;
+		}
+	}
+
+	return NULL;
 }
 
 void LLConversationLog::removeConversation(const LLConversation& conversation)
@@ -271,34 +333,7 @@ void LLConversationLog::removeObserver(LLConversationLogObserver* observer)
 
 void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
-	if (session)
-	{
-		if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType)
-		{
-			LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session));
-		}
-		else
-		{
-			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
-		}
-	}
+	logConversation(session_id);
 }
 
 void LLConversationLog::cache()
@@ -442,25 +477,13 @@ void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& sessi
 	}
 }
 
-void LLConversationLog::onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state)
+void LLConversationLog::onNewMessageReceived(const LLSD& data)
 {
-	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
-		}
-	}
+	const LLUUID session_id = data["session_id"].asUUID();
+	logConversation(session_id);
 }
 
 void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session)
 {
-	LLConversation conversation(*session);
-	conversation.setConverstionName(av_name.getCompleteName());
-	LLConversationLog::instance().logConversation(conversation);
-	session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2));
+	updateConversationName(session->mSessionID, av_name.getCompleteName());
 }
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 16be37d67a..ffd27f7e20 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -57,15 +57,18 @@ 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; }
 	void	setConverstionName(std::string conv_name) { mConversationName = conv_name; }
 
 	bool isOlderThan(U32 days) const;
 
+	/*
+	 * updates last interaction time
+	 */
+	void updateTimestamp();
+
 	/*
 	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
 	 */
@@ -86,7 +89,7 @@ private:
 
 	boost::signals2::connection mIMFloaterShowedConnection;
 
-	time_t			mTime; // start time of conversation
+	time_t			mTime; // last interaction time
 	SessionType		mConversationType;
 	std::string		mConversationName;
 	std::string		mHistoryFileName;
@@ -94,8 +97,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
+	std::string		mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm
 };
 
 /**
@@ -112,32 +114,26 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse
 	friend class LLSingleton<LLConversationLog>;
 public:
 
-	/**
-	 * adds conversation to the conversation list and notifies observers
-	 */
-	void logConversation(const LLConversation& conversation);
 	void removeConversation(const LLConversation& conversation);
 
 	/**
 	 * Returns first conversation with matched session_id
 	 */
-	const LLConversation* getConversation(const LLUUID& session_id);
+	const LLConversation*				getConversation(const LLUUID& session_id);
+	const std::vector<LLConversation>&	getConversations() { return mConversations; }
 
 	void addObserver(LLConversationLogObserver* observer);
 	void removeObserver(LLConversationLogObserver* observer);
 
-	const std::vector<LLConversation>& getConversations() { return mConversations; }
-
 	// LLIMSessionObserver triggers
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-	virtual void sessionRemoved(const LLUUID& session_id);
+	virtual void sessionRemoved(const LLUUID& session_id){}											// Stub
 	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){};								// Stub
 	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){};	// Stub
 
 	void notifyObservers();
-	void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask);
 
-	void onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state);
+	void onNewMessageReceived(const LLSD& data);
 
 	/**
 	 * public method which is called on viewer exit to save conversation log
@@ -148,6 +144,13 @@ private:
 
 	LLConversationLog();
 
+	/**
+	 * adds conversation to the conversation list and notifies observers
+	 */
+	void logConversation(const LLUUID& session_id);
+
+	void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask);
+
 	void observeIMSession();
 
 	/**
@@ -161,11 +164,19 @@ private:
 
 	void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session);
 
+	void createConversation(const LLUUID& session_id);
+	void updateConversationTimestamp(LLConversation* conversation);
+	void updateConversationName(const LLUUID& session_id, const std::string& name);
+
+	LLConversation* findConversation(const LLUUID& session_id);
+
 	typedef std::vector<LLConversation> conversations_vec_t;
 	std::vector<LLConversation>				mConversations;
 	std::set<LLConversationLogObserver*>	mObservers;
 
 	LLFriendObserver* mFriendObserver;		// Observer of the LLAvatarTracker instance
+
+	boost::signals2::connection newMessageSignalConnection;
 };
 
 class LLConversationLogObserver
@@ -174,7 +185,8 @@ public:
 
 	enum EConversationChange
 		{
-			VOICE_STATE = 1
+			CHANGED_TIME = 1, // last interaction time changed
+			CHANGED_NAME = 2  // conversation name changed
 		};
 
 	virtual ~LLConversationLogObserver(){}
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index d39e090c22..429e99f7ad 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -143,22 +143,32 @@ void LLConversationLogList::changed()
 
 void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
 {
-	if (mask & LLConversationLogObserver::VOICE_STATE)
+	LLConversationLogListItem* item = getConversationLogListItem(session_id);
+
+	if (!item)
 	{
-		std::vector<LLPanel*> panels;
-		LLFlatListViewEx::getItems(panels);
+		return;
+	}
 
-		std::vector<LLPanel*>::iterator iter = panels.begin();
+	if (mask & LLConversationLogObserver::CHANGED_TIME)
+	{
+		item->updateTimestamp();
 
-		for (; iter != panels.end(); ++iter)
+		// if list is sorted by date and a date of some item has changed,
+		// than the whole list should be rebuilt
+		if (E_SORT_BY_DATE == getSortOrder())
 		{
-			LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter);
-
-			if (item && session_id == item->getConversation()->getSessionID() && !item->getConversation()->isConversationPast())
-			{
-				item->initIcons();
-				return;
-			}
+			mIsDirty = true;
+		}
+	}
+	else if (mask & LLConversationLogObserver::CHANGED_NAME)
+	{
+		item->updateName();
+		// if list is sorted by name and a name of some item has changed,
+		// than the whole list should be rebuilt
+		if (E_SORT_BY_DATE == getSortOrder())
+		{
+			mIsDirty = true;
 		}
 	}
 }
@@ -401,6 +411,29 @@ const LLConversation* LLConversationLogList::getSelectedConversation()
 	return NULL;
 }
 
+LLConversationLogListItem* LLConversationLogList::getConversationLogListItem(const LLUUID& session_id)
+{
+	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())
+		{
+			return item;
+		}
+	}
+
+	return NULL;
+}
+
+LLConversationLogList::ESortOrder LLConversationLogList::getSortOrder()
+{
+	return static_cast<ESortOrder>(gSavedSettings.getU32("CallLogSortOrder"));
+}
+
 bool LLConversationLogListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
 {
 	const LLConversationLogListItem* conversation_item1 = dynamic_cast<const LLConversationLogListItem*>(item1);
diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h
index 5e7fc0a9fb..62ec57e09e 100644
--- a/indra/newview/llconversationloglist.h
+++ b/indra/newview/llconversationloglist.h
@@ -43,6 +43,12 @@ class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogOb
 {
 	LOG_CLASS(LLConversationLogList);
 public:
+
+	typedef enum e_sort_oder{
+		E_SORT_BY_NAME = 0,
+		E_SORT_BY_DATE = 1,
+	} ESortOrder;
+
 	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
 	{
 		Params(){};
@@ -90,6 +96,9 @@ private:
 	LLIMModel::LLIMSession::SType getSelectedSessionType();
 	const LLConversationLogListItem* getSelectedConversationPanel();
 	const LLConversation* getSelectedConversation();
+	LLConversationLogListItem* getConversationLogListItem(const LLUUID& session_id);
+
+	ESortOrder getSortOrder();
 
 	LLHandle<LLToggleableMenu>	mContextMenu;
 	bool mIsDirty;
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
index dddf216592..fac6130371 100644
--- a/indra/newview/llconversationloglistitem.cpp
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -117,6 +117,16 @@ void LLConversationLogListItem::initIcons()
 	}
 }
 
+void LLConversationLogListItem::updateTimestamp()
+{
+	mConversationDate->setValue(mConversation->getTimestamp());
+}
+
+void LLConversationLogListItem::updateName()
+{
+	mConversationName->setValue(mConversation->getConversationName());
+}
+
 void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask)
 {
 	getChildView("hovered_icon")->setVisible(true);
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
index 2aaafa0fba..1bf7a0ed93 100644
--- a/indra/newview/llconversationloglistitem.h
+++ b/indra/newview/llconversationloglistitem.h
@@ -64,10 +64,16 @@ public:
 
 	void onDoubleClick();
 
-	void initIcons();
+	/**
+	 * updates string value of last interaction time from conversation
+	 */
+	void updateTimestamp();
+	void updateName();
 
 private:
 
+	void initIcons();
+
 	const LLConversation* mConversation;
 
 	LLTextBox*		mConversationName;
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index 4375ce5726..7b4c999e52 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -45,11 +45,11 @@ BOOL LLFloaterConversationLog::postBuild()
 
 	switch (gSavedSettings.getU32("CallLogSortOrder"))
 	{
-	case E_SORT_BY_NAME:
+	case LLConversationLogList::E_SORT_BY_NAME:
 		mConversationLogList->sortByName();
 		break;
 
-	case E_SORT_BY_DATE:
+	case LLConversationLogList::E_SORT_BY_DATE:
 		mConversationLogList->sortByDate();
 		break;
 	}
@@ -87,12 +87,12 @@ void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
 	if ("sort_by_name" == command_name)
 	{
 		mConversationLogList->sortByName();
-		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_NAME);
+		gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_NAME);
 	}
 	else if ("sort_by_date" == command_name)
 	{
 		mConversationLogList->sortByDate();
-		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_DATE);
+		gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_DATE);
 	}
 	else if ("sort_friends_on_top" == command_name)
 	{
@@ -117,11 +117,11 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
 
 	if ("sort_by_name" == command_name)
 	{
-		return sort_order == E_SORT_BY_NAME;
+		return sort_order == LLConversationLogList::E_SORT_BY_NAME;
 	}
 	else if ("sort_by_date" == command_name)
 	{
-		return sort_order == E_SORT_BY_DATE;
+		return sort_order == LLConversationLogList::E_SORT_BY_DATE;
 	}
 	else if ("sort_friends_on_top" == command_name)
 	{
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
index 7d788c0290..e971330f3d 100644
--- a/indra/newview/llfloaterconversationlog.h
+++ b/indra/newview/llfloaterconversationlog.h
@@ -34,11 +34,6 @@ class LLFloaterConversationLog : public LLFloater
 {
 public:
 
-	typedef enum e_sort_oder{
-		E_SORT_BY_NAME = 0,
-		E_SORT_BY_DATE = 1,
-	} ESortOrder;
-
 	LLFloaterConversationLog(const LLSD& key);
 	virtual ~LLFloaterConversationLog(){};
 
-- 
cgit v1.2.3


From cb8ce1141837cc450756764e03a4564f8ab0c9eb Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 11 Sep 2012 18:37:05 +0300
Subject: CHUI-336 FIXED (Remove Description label and field from Chat history
 viewer)

- Removed lineeditor and text box from code and xml
---
 indra/newview/llfloaterconversationpreview.cpp     |  2 --
 .../xui/en/floater_conversation_preview.xml        | 28 ++--------------------
 2 files changed, 2 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 9ea35fcbad..dbcf154ef2 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -65,8 +65,6 @@ BOOL LLFloaterConversationPreview::postBuild()
 	std::string title = getString("Title", args);
 	setTitle(title);
 
-	getChild<LLLineEditor>("description")->setValue(name);
-
 	LLLogChat::loadChatHistory(file, mMessages, true);
 	mCurrentPage = mMessages.size() / mPageSize;
 
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
index d74c2c252d..825a88e4e1 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -14,41 +14,17 @@
      name="Title">
         CONVERSATION: [NAME]
     </floater.string>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     font="SansSerif"
-     height="19"
-     layout="topleft"
-     left="10"
-     name="desc txt"
-     top="22"
-     width="90">
-        Description:
-    </text>
-    <line_editor
-     border_style="line"
-     border_thickness="1"
-     enabled="false"
-     follows="left|top|right"
-     font="SansSerif"
-     height="22"
-     layout="topleft"
-     left_pad="0"
-     max_length_bytes="127"
-     name="description"
-     width="296" />
     <chat_history
      font="SansSerifSmall"
      follows="all"
      visible="true"
-     height="310"
+     height="330"
      name="chat_history"
      notify_unread_msg="false"
      parse_highlights="true"
      parse_urls="true"
      left="5"
+     top_pad="25"
      width="390">
     </chat_history>
     <text
-- 
cgit v1.2.3


From 51725b3898df96aa5819d86d1e8e7c71b47304f2 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 12 Sep 2012 14:09:13 +0300
Subject: CHUI-335 FIXED (Alpha text allowed in page spinner in chat history
 viewer)

- Added XML parameter "allow_digits_only" to spinner control widget, which disables/enables ability to input alpha text.
- Disabled ability to enter alpha text in page spinner in chat history viewer
---
 indra/llui/llspinctrl.cpp                                           | 5 +++++
 indra/llui/llspinctrl.h                                             | 1 +
 indra/newview/skins/default/xui/en/floater_conversation_preview.xml | 1 +
 3 files changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 934879cdfd..8a728df2e7 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params()
 :	label_width("label_width"),
 	decimal_digits("decimal_digits"),
 	allow_text_entry("allow_text_entry", true),
+	allow_digits_only("allow_digits_only", false),
 	label_wrap("label_wrap", false),
 	text_enabled_color("text_enabled_color"),
 	text_disabled_color("text_disabled_color"),
@@ -129,6 +130,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
 	params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
 	mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
 	mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
+	if (p.allow_digits_only)
+	{
+		mEditor->setPrevalidateInput(LLTextValidate::validateNonNegativeS32NoSpace);
+	}
 	//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
 	// than when it doesn't.  Instead, if you always have to double click to select all the text, 
 	// it's easier to understand
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index 87814f838e..e34add879d 100644
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -44,6 +44,7 @@ public:
 		Optional<S32> label_width;
 		Optional<U32> decimal_digits;
 		Optional<bool> allow_text_entry;
+		Optional<bool> allow_digits_only;
 		Optional<bool> label_wrap;
 
 		Optional<LLUIColor> text_enabled_color;
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
index 825a88e4e1..0e5af67f68 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -39,6 +39,7 @@
      width="35">
     </text>
     <spinner
+     allow_digits_only="true"
      decimal_digits="0"
      follows="bottom|right"
      height="23"
-- 
cgit v1.2.3